ETH Price: $2,514.35 (-1.50%)

Transaction Decoder

Block:
22818653 at Jun-30-2025 05:13:23 PM +UTC
Transaction Fee:
0.000541391831621126 ETH $1.36
Gas Used:
111,547 Gas / 4.853486258 Gwei

Emitted Events:

239 Coins.OperatorSet( [Receiver] 0x9c63762fd8789f99e4a8bdaa92d7364be1c56727, ZAMM, True )
240 Coins.Transfer( ZAMM, [Receiver] 0x9c63762fd8789f99e4a8bdaa92d7364be1c56727, ZAMM, 754922417686844852297650605102897991409579903666, 7074678456927887571706560 )
241 ZAMM.Sync( poolId=86747398623582161866936615244950034759064619359605100395857260863866475167514, reserve0=24957376236064797, reserve1=21000000000000000000000000 )
242 ZAMM.Swap( poolId=86747398623582161866936615244950034759064619359605100395857260863866475167514, sender=[Receiver] 0x9c63762fd8789f99e4a8bdaa92d7364be1c56727, amount0In=0, amount1In=7074678456927887571706560, amount0Out=12552655056335679, amount1Out=0, to=[Receiver] 0x9c63762fd8789f99e4a8bdaa92d7364be1c56727 )

Account State Difference:

  Address   Before After State Difference Code
0x00000000...40b24C860
(NANI: AMM ZAMM)
79.150807587453221887 Eth79.138254932396886208 Eth0.012552655056335679
0x00000000...029651eE8
0x9C63762f...be1c56727
0.112231344138052923 Eth
Nonce: 6
0.124242607362767476 Eth
Nonce: 8
0.012011263224714553From: 0 To: 22892026855592066050609947431602401211538835161166308139
(BuilderNet)
29.859628482769433783 Eth29.859851576769433783 Eth0.000223094

Execution Trace

0x9c63762fd8789f99e4a8bdaa92d7364be1c56727.e9ae5c53( )
  • Coins.setOperator( operator=0x00000000000008882D72EfA6cCE4B6a40b24C860, approved=True ) => ( True )
  • ZAMM.swapExactIn( poolKey=[{name:id0, type:uint256, order:1, indexed:false, value:0, valueString:0}, {name:id1, type:uint256, order:2, indexed:false, value:754922417686844852297650605102897991409579903666, valueString:754922417686844852297650605102897991409579903666}, {name:token0, type:address, order:3, indexed:false, value:0x0000000000000000000000000000000000000000, valueString:0x0000000000000000000000000000000000000000}, {name:token1, type:address, order:4, indexed:false, value:0x0000000000009710cd229bF635c4500029651eE8, valueString:0x0000000000009710cd229bF635c4500029651eE8}, {name:swapFee, type:uint96, order:5, indexed:false, value:100, valueString:100}], amountIn=7074678456927887571706560, amountOutMin=12301601955208965, zeroForOne=False, to=0x9C63762fD8789f99E4a8bdaA92d7364be1c56727, deadline=1751304788 ) => ( amountOut=12552655056335679 )
    • Coins.transferFrom( from=0x9C63762fD8789f99E4a8bdaA92d7364be1c56727, to=0x00000000000008882D72EfA6cCE4B6a40b24C860, id=754922417686844852297650605102897991409579903666, amount=7074678456927887571706560 ) => ( True )
    • ETH 0.012552655056335679 0x9c63762fd8789f99e4a8bdaa92d7364be1c56727.CALL( )
      File 1 of 2: Coins
      // SPDX-License-Identifier: MIT
      pragma solidity 0.8.29;
      error OnlyExternal();
      error Unauthorized();
      error InvalidMetadata();
      error DeploymentFailed();
      /// @title Coins
      /// @notice Singleton for ERC6909 & ERC20s
      /// @author z0r0z & 0xc0de4c0ffee & kobuta23
      contract Coins {
          event MetadataSet(uint256 indexed);
          event OwnershipTransferred(uint256 indexed);
          event OperatorSet(address indexed, address indexed, bool);
          event Approval(address indexed, address indexed, uint256 indexed, uint256);
          event Transfer(address, address indexed, address indexed, uint256 indexed, uint256);
          Token immutable implementation = new Token{salt: keccak256("")}();
          mapping(uint256 id => Metadata) _metadata;
          mapping(uint256 id => uint256) public totalSupply;
          mapping(uint256 id => address owner) public ownerOf;
          mapping(address owner => mapping(uint256 id => uint256)) public balanceOf;
          mapping(address owner => mapping(address operator => bool)) public isOperator;
          mapping(address owner => mapping(address spender => mapping(uint256 id => uint256))) public
              allowance;
          modifier onlyOwnerOf(uint256 id) {
              require(msg.sender == ownerOf[id], Unauthorized());
              _;
          }
          constructor() payable {}
          // METADATA
          struct Metadata {
              string name;
              string symbol;
              string tokenURI;
          }
          function name(uint256 id) public view returns (string memory) {
              Metadata storage meta = _metadata[id];
              return bytes(meta.tokenURI).length != 0 ? meta.name : Token(address(uint160(id))).name();
          }
          function symbol(uint256 id) public view returns (string memory) {
              Metadata storage meta = _metadata[id];
              return bytes(meta.tokenURI).length != 0 ? meta.symbol : Token(address(uint160(id))).symbol();
          }
          function decimals(uint256 id) public view returns (uint8) {
              return bytes(_metadata[id].tokenURI).length != 0
                  ? 18
                  : uint8(Token(address(uint160(id))).decimals());
          }
          function tokenURI(uint256 id) public view returns (string memory) {
              return _metadata[id].tokenURI;
          }
          // CREATION
          function create(
              string calldata _name,
              string calldata _symbol,
              string calldata _tokenURI,
              address owner,
              uint256 supply
          ) public {
              require(bytes(_tokenURI).length != 0, InvalidMetadata());
              uint256 id;
              Token _implementation = implementation;
              bytes32 salt = keccak256(abi.encodePacked(_name, address(this), _symbol));
              assembly ("memory-safe") {
                  mstore(0x21, 0x5af43d3d93803e602a57fd5bf3)
                  mstore(0x14, _implementation)
                  mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73)
                  id := create2(0, 0x0c, 0x35, salt)
                  if iszero(id) {
                      mstore(0x00, 0x30116425) // `DeploymentFailed()`
                      revert(0x1c, 0x04)
                  }
                  mstore(0x21, 0)
              }
              _metadata[id] = Metadata(_name, _symbol, _tokenURI);
              emit Transfer(
                  msg.sender,
                  address(0),
                  ownerOf[id] = owner,
                  id,
                  balanceOf[owner][id] = totalSupply[id] = supply
              );
          }
          // WRAPPING
          function wrap(Token token, uint256 amount) public {
              uint256 id = uint160(address(token));
              require(bytes(_metadata[id].tokenURI).length == 0, OnlyExternal());
              token.transferFrom(msg.sender, address(this), amount);
              _mint(msg.sender, id, amount);
          }
          function unwrap(Token token, uint256 amount) public {
              _burn(msg.sender, uint256(uint160(address(token))), amount);
              token.transfer(msg.sender, amount);
          }
          // MINT/BURN
          function mint(address to, uint256 id, uint256 amount) public onlyOwnerOf(id) {
              _mint(to, id, amount);
          }
          function burn(uint256 id, uint256 amount) public {
              _burn(msg.sender, id, amount);
          }
          // GOVERNANCE
          function setMetadata(uint256 id, string calldata _tokenURI) public onlyOwnerOf(id) {
              require(bytes(_tokenURI).length != 0, InvalidMetadata());
              _metadata[id].tokenURI = _tokenURI;
              emit MetadataSet(id);
          }
          function transferOwnership(uint256 id, address newOwner) public onlyOwnerOf(id) {
              ownerOf[id] = newOwner;
              emit OwnershipTransferred(id);
          }
          // ERC6909
          function transfer(address to, uint256 id, uint256 amount) public returns (bool) {
              balanceOf[msg.sender][id] -= amount;
              unchecked {
                  balanceOf[to][id] += amount;
              }
              emit Transfer(msg.sender, msg.sender, to, id, amount);
              return true;
          }
          function transferFrom(address from, address to, uint256 id, uint256 amount)
              public
              returns (bool)
          {
              if (msg.sender != address(uint160(id))) {
                  if (!isOperator[from][msg.sender]) {
                      if (allowance[from][msg.sender][id] != type(uint256).max) {
                          allowance[from][msg.sender][id] -= amount;
                      }
                  }
              }
              balanceOf[from][id] -= amount;
              unchecked {
                  balanceOf[to][id] += amount;
              }
              emit Transfer(msg.sender, from, to, id, amount);
              return true;
          }
          function approve(address spender, uint256 id, uint256 amount) public returns (bool) {
              allowance[msg.sender][spender][id] = amount;
              emit Approval(msg.sender, spender, id, amount);
              return true;
          }
          function setOperator(address operator, bool approved) public returns (bool) {
              isOperator[msg.sender][operator] = approved;
              emit OperatorSet(msg.sender, operator, approved);
              return true;
          }
          // ERC20 APPROVAL
          function setAllowance(address owner, address spender, uint256 id, uint256 amount)
              public
              payable
              returns (bool)
          {
              require(msg.sender == address(uint160(id)), Unauthorized());
              allowance[owner][spender][id] = amount;
              emit Approval(owner, spender, id, amount);
              return true;
          }
          // ERC165
          function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
              return interfaceId == 0x01ffc9a7 // ERC165
                  || interfaceId == 0x0f632fb3; // ERC6909
          }
          // INTERNAL MINT/BURN
          function _mint(address to, uint256 id, uint256 amount) internal {
              totalSupply[id] += amount;
              unchecked {
                  balanceOf[to][id] += amount;
              }
              emit Transfer(msg.sender, address(0), to, id, amount);
          }
          function _burn(address from, uint256 id, uint256 amount) internal {
              balanceOf[from][id] -= amount;
              unchecked {
                  totalSupply[id] -= amount;
              }
              emit Transfer(msg.sender, from, address(0), id, amount);
          }
      }
      contract Token {
          event Approval(address indexed, address indexed, uint256);
          event Transfer(address indexed, address indexed, uint256);
          uint256 public constant decimals = 18;
          address immutable coins = msg.sender;
          constructor() payable {}
          function name() public view returns (string memory) {
              return Coins(coins).name(uint160(address(this)));
          }
          function symbol() public view returns (string memory) {
              return Coins(coins).symbol(uint160(address(this)));
          }
          function totalSupply() public view returns (uint256) {
              return Coins(coins).totalSupply(uint160(address(this)));
          }
          function balanceOf(address owner) public view returns (uint256) {
              return Coins(coins).balanceOf(owner, uint160(address(this)));
          }
          function allowance(address owner, address spender) public view returns (uint256) {
              if (Coins(coins).isOperator(owner, spender)) return type(uint256).max;
              return Coins(coins).allowance(owner, spender, uint160(address(this)));
          }
          function approve(address spender, uint256 amount) public returns (bool) {
              emit Approval(msg.sender, spender, amount);
              return Coins(coins).setAllowance(msg.sender, spender, uint160(address(this)), amount);
          }
          function transfer(address to, uint256 amount) public returns (bool) {
              emit Transfer(msg.sender, to, amount);
              return Coins(coins).transferFrom(msg.sender, to, uint160(address(this)), amount);
          }
          function transferFrom(address from, address to, uint256 amount) public returns (bool) {
              require(allowance(from, msg.sender) >= amount, Unauthorized());
              emit Transfer(from, to, amount);
              return Coins(coins).transferFrom(from, to, uint160(address(this)), amount);
          }
      }
      

      File 2 of 2: ZAMM
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.29;
      import "./ZERC6909.sol";
      import "./utils/Math.sol";
      import "./utils/TransferHelper.sol";
      // maximally simple constant product AMM singleton
      // minted by z0r0z as concentric liquidity backend
      contract ZAMM is ZERC6909 {
          uint256 constant MINIMUM_LIQUIDITY = 1000;
          uint256 constant MAX_FEE = 10000; // 100%
          mapping(uint256 poolId => Pool) public pools;
          struct PoolKey {
              uint256 id0;
              uint256 id1;
              address token0;
              address token1;
              uint96 swapFee;
          }
          struct Pool {
              uint112 reserve0;
              uint112 reserve1;
              uint32 blockTimestampLast;
              uint256 price0CumulativeLast;
              uint256 price1CumulativeLast;
              uint256 kLast; // `reserve0` * `reserve1`, as of immediately after the most recent liquidity event
              uint256 supply;
          }
          // Solady (https://github.com/Vectorized/soledge/blob/main/src/utils/ReentrancyGuard.sol)
          error Reentrancy();
          modifier lock() {
              assembly ("memory-safe") {
                  if tload(0x929eee149b4bd21268) {
                      mstore(0x00, 0xab143c06) // `Reentrancy()`
                      revert(0x1c, 0x04)
                  }
                  tstore(0x929eee149b4bd21268, address())
              }
              _;
              assembly ("memory-safe") {
                  tstore(0x929eee149b4bd21268, 0)
              }
          }
          // ** TRANSFER
          function _safeTransfer(address token, address to, uint256 id, uint256 amount) internal {
              if (to == address(this)) {
                  assembly ("memory-safe") {
                      let m := mload(0x40)
                      mstore(0x00, caller())
                      mstore(0x20, token)
                      mstore(0x40, id)
                      let slot := keccak256(0x00, 0x60)
                      tstore(slot, add(tload(slot), amount))
                      mstore(0x40, m)
                  }
              } else if (token == address(this)) {
                  _mint(to, id, amount);
              } else if (token == address(0)) {
                  safeTransferETH(to, amount);
              } else if (id == 0) {
                  safeTransfer(token, to, amount);
              } else {
                  ZERC6909(token).transfer(to, id, amount);
              }
          }
          function _safeTransferFrom(address token, uint256 id, uint256 amount) internal {
              if (token == address(this)) {
                  _burn(id, amount);
              } else if (id == 0) {
                  safeTransferFrom(token, amount);
              } else {
                  ZERC6909(token).transferFrom(msg.sender, address(this), id, amount);
              }
          }
          event Mint(uint256 indexed poolId, address indexed sender, uint256 amount0, uint256 amount1);
          event Burn(
              uint256 indexed poolId,
              address indexed sender,
              uint256 amount0,
              uint256 amount1,
              address indexed to
          );
          event Swap(
              uint256 indexed poolId,
              address indexed sender,
              uint256 amount0In,
              uint256 amount1In,
              uint256 amount0Out,
              uint256 amount1Out,
              address indexed to
          );
          event Sync(uint256 indexed poolId, uint112 reserve0, uint112 reserve1);
          constructor() payable {
              assembly ("memory-safe") {
                  sstore(0x00, origin())
              }
          }
          // ** INTERNAL
          error Overflow();
          // update reserves and, on the first call per block, price accumulators for the given pool `poolId`
          function _update(
              Pool storage pool,
              uint256 poolId,
              uint256 balance0,
              uint256 balance1,
              uint112 reserve0,
              uint112 reserve1
          ) internal {
              unchecked {
                  require(balance0 <= type(uint112).max, Overflow());
                  require(balance1 <= type(uint112).max, Overflow());
                  uint32 blockTimestamp = uint32(block.timestamp % 2 ** 32);
                  uint32 timeElapsed = blockTimestamp - pool.blockTimestampLast; // overflow is desired
                  if (timeElapsed > 0 && reserve0 != 0 && reserve1 != 0) {
                      // * never overflows, and + overflow is desired
                      pool.price0CumulativeLast +=
                          uint256(uqdiv(encode(reserve1), reserve0)) * timeElapsed;
                      pool.price1CumulativeLast +=
                          uint256(uqdiv(encode(reserve0), reserve1)) * timeElapsed;
                  }
                  pool.blockTimestampLast = blockTimestamp;
                  emit Sync(poolId, pool.reserve0 = uint112(balance0), pool.reserve1 = uint112(balance1));
              }
          }
          // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
          function _mintFee(Pool storage pool, uint256 poolId, uint112 reserve0, uint112 reserve1)
              internal
              returns (bool feeOn)
          {
              address feeTo;
              assembly ("memory-safe") {
                  feeTo := sload(0x20)
                  feeOn := iszero(iszero(feeTo))
              }
              if (feeOn) {
                  if (pool.kLast != 0) {
                      uint256 rootK = sqrt(uint256(reserve0) * reserve1);
                      uint256 rootKLast = sqrt(pool.kLast);
                      if (rootK > rootKLast) {
                          uint256 numerator = pool.supply * (rootK - rootKLast);
                          uint256 denominator = rootK * 5 + rootKLast;
                          uint256 liquidity;
                          unchecked {
                              liquidity = numerator / denominator;
                              if (liquidity > 0) {
                                  _mint(feeTo, poolId, liquidity);
                              }
                              pool.supply += liquidity;
                          }
                      }
                  }
              } else if (pool.kLast != 0) {
                  delete pool.kLast;
              }
          }
          // ** SWAPPERS
          error Expired();
          error InvalidMsgVal();
          error InsufficientLiquidity();
          error InsufficientInputAmount();
          error InsufficientOutputAmount();
          function swapExactIn(
              PoolKey calldata poolKey,
              uint256 amountIn,
              uint256 amountOutMin,
              bool zeroForOne,
              address to,
              uint256 deadline
          ) public payable lock returns (uint256 amountOut) {
              require(deadline >= block.timestamp, Expired());
              require(amountIn != 0, InsufficientInputAmount());
              uint256 poolId = _getPoolId(poolKey);
              Pool storage pool = pools[poolId];
              (uint112 reserve0, uint112 reserve1) = (pool.reserve0, pool.reserve1);
              bool credited;
              if (zeroForOne) {
                  credited = _useTransientBalance(poolKey.token0, poolKey.id0, amountIn);
                  if (credited) require(msg.value == 0, InvalidMsgVal());
              } else {
                  credited = _useTransientBalance(poolKey.token1, poolKey.id1, amountIn);
              }
              if (!credited) {
                  if (zeroForOne) {
                      if (poolKey.token0 == address(0)) {
                          require(msg.value == amountIn, InvalidMsgVal());
                      } else {
                          require(msg.value == 0, InvalidMsgVal());
                          _safeTransferFrom(poolKey.token0, poolKey.id0, amountIn);
                      }
                  } else {
                      require(msg.value == 0, InvalidMsgVal());
                      _safeTransferFrom(poolKey.token1, poolKey.id1, amountIn);
                  }
              }
              if (zeroForOne) {
                  amountOut = _getAmountOut(amountIn, reserve0, reserve1, poolKey.swapFee);
                  require(amountOut != 0, InsufficientOutputAmount());
                  require(amountOut >= amountOutMin, InsufficientOutputAmount());
                  require(amountOut < reserve1, InsufficientLiquidity());
                  _safeTransfer(poolKey.token1, to, poolKey.id1, amountOut);
                  _update(pool, poolId, reserve0 + amountIn, reserve1 - amountOut, reserve0, reserve1);
                  emit Swap(poolId, msg.sender, amountIn, 0, 0, amountOut, to);
              } else {
                  amountOut = _getAmountOut(amountIn, reserve1, reserve0, poolKey.swapFee);
                  require(amountOut != 0, InsufficientOutputAmount());
                  require(amountOut >= amountOutMin, InsufficientOutputAmount());
                  require(amountOut < reserve0, InsufficientLiquidity());
                  _safeTransfer(poolKey.token0, to, poolKey.id0, amountOut);
                  _update(pool, poolId, reserve0 - amountOut, reserve1 + amountIn, reserve0, reserve1);
                  emit Swap(poolId, msg.sender, 0, amountIn, amountOut, 0, to);
              }
          }
          function swapExactOut(
              PoolKey calldata poolKey,
              uint256 amountOut,
              uint256 amountInMax,
              bool zeroForOne,
              address to,
              uint256 deadline
          ) public payable lock returns (uint256 amountIn) {
              require(deadline >= block.timestamp, Expired());
              require(amountOut != 0, InsufficientOutputAmount());
              uint256 poolId = _getPoolId(poolKey);
              Pool storage pool = pools[poolId];
              (uint112 reserve0, uint112 reserve1) = (pool.reserve0, pool.reserve1);
              bool credited;
              if (zeroForOne) {
                  require(amountOut < reserve1, InsufficientLiquidity());
                  amountIn = _getAmountIn(amountOut, reserve0, reserve1, poolKey.swapFee);
                  require(amountIn <= amountInMax, InsufficientInputAmount());
                  credited = _useTransientBalance(poolKey.token0, poolKey.id0, amountIn);
                  if (credited) require(msg.value == 0, InvalidMsgVal());
                  if (!credited) {
                      if (poolKey.token0 == address(0)) {
                          require(msg.value >= amountIn, InvalidMsgVal());
                          if (msg.value > amountIn) {
                              unchecked {
                                  safeTransferETH(msg.sender, msg.value - amountIn);
                              }
                          }
                      } else {
                          require(msg.value == 0, InvalidMsgVal());
                          _safeTransferFrom(poolKey.token0, poolKey.id0, amountIn);
                      }
                  }
                  _safeTransfer(poolKey.token1, to, poolKey.id1, amountOut);
                  _update(pool, poolId, reserve0 + amountIn, reserve1 - amountOut, reserve0, reserve1);
                  emit Swap(poolId, msg.sender, amountIn, 0, 0, amountOut, to);
              } else {
                  require(amountOut < reserve0, InsufficientLiquidity());
                  amountIn = _getAmountIn(amountOut, reserve1, reserve0, poolKey.swapFee);
                  require(amountIn <= amountInMax, InsufficientInputAmount());
                  credited = _useTransientBalance(poolKey.token1, poolKey.id1, amountIn);
                  if (!credited) {
                      require(msg.value == 0, InvalidMsgVal());
                      _safeTransferFrom(poolKey.token1, poolKey.id1, amountIn);
                  }
                  _safeTransfer(poolKey.token0, to, poolKey.id0, amountOut);
                  _update(pool, poolId, reserve0 - amountOut, reserve1 + amountIn, reserve0, reserve1);
                  emit Swap(poolId, msg.sender, 0, amountIn, amountOut, 0, to);
              }
          }
          error K();
          // this low-level function should be called from a contract which performs important safety checks
          function swap(
              PoolKey calldata poolKey,
              uint256 amount0Out,
              uint256 amount1Out,
              address to,
              bytes calldata data
          ) public lock {
              require(amount0Out > 0 || amount1Out > 0, InsufficientOutputAmount());
              uint256 poolId = _getPoolId(poolKey);
              Pool storage pool = pools[poolId];
              (uint112 reserve0, uint112 reserve1) = (pool.reserve0, pool.reserve1);
              require(amount0Out < reserve0, InsufficientLiquidity());
              require(amount1Out < reserve1, InsufficientLiquidity());
              // optimistically transfer tokens - if `to` is `this`, tstore for multihop
              if (amount0Out > 0) _safeTransfer(poolKey.token0, to, poolKey.id0, amount0Out);
              if (amount1Out > 0) _safeTransfer(poolKey.token1, to, poolKey.id1, amount1Out);
              if (data.length > 0) {
                  IZAMMCallee(to).zammCall(poolId, msg.sender, amount0Out, amount1Out, data);
              }
              uint256 balance0 = reserve0 + _getTransientBalance(poolKey.token0, poolKey.id0) - amount0Out;
              uint256 balance1 = reserve1 + _getTransientBalance(poolKey.token1, poolKey.id1) - amount1Out;
              uint256 amount0In;
              uint256 amount1In;
              unchecked {
                  amount0In = balance0 > reserve0 - amount0Out ? balance0 - (reserve0 - amount0Out) : 0;
                  amount1In = balance1 > reserve1 - amount1Out ? balance1 - (reserve1 - amount1Out) : 0;
              }
              require(amount0In > 0 || amount1In > 0, InsufficientInputAmount());
              uint256 balance0Adjusted = (balance0 * 10000) - (amount0In * poolKey.swapFee);
              uint256 balance1Adjusted = (balance1 * 10000) - (amount1In * poolKey.swapFee);
              require(
                  balance0Adjusted * balance1Adjusted >= (uint256(reserve0) * reserve1) * 10000 ** 2, K()
              );
              _update(pool, poolId, balance0, balance1, reserve0, reserve1);
              emit Swap(poolId, msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
          }
          // ** LIQ MGMT
          error InvalidSwapFee();
          error InvalidPoolTokens();
          error InsufficientLiquidityMinted();
          function addLiquidity(
              PoolKey calldata poolKey,
              uint256 amount0Desired,
              uint256 amount1Desired,
              uint256 amount0Min,
              uint256 amount1Min,
              address to,
              uint256 deadline
          ) public payable lock returns (uint256 amount0, uint256 amount1, uint256 liquidity) {
              require(deadline >= block.timestamp, Expired());
              uint256 poolId = _getPoolId(poolKey);
              Pool storage pool = pools[poolId];
              (uint112 reserve0, uint112 reserve1, uint256 supply) =
                  (pool.reserve0, pool.reserve1, pool.supply);
              bool feeOn;
              if (supply != 0) {
                  feeOn = _mintFee(pool, poolId, reserve0, reserve1);
                  supply = pool.supply;
              } else {
                  assembly ("memory-safe") {
                      feeOn := iszero(iszero(sload(0x20)))
                  }
              }
              if (supply == 0) {
                  (amount0, amount1) = (amount0Desired, amount1Desired);
              } else {
                  uint256 amount1Optimal = mulDiv(amount0Desired, reserve1, reserve0);
                  if (amount1Optimal <= amount1Desired) {
                      require(amount1Optimal >= amount1Min, InsufficientOutputAmount());
                      (amount0, amount1) = (amount0Desired, amount1Optimal);
                  } else {
                      uint256 amount0Optimal = mulDiv(amount1Desired, reserve0, reserve1);
                      assert(amount0Optimal <= amount0Desired);
                      require(amount0Optimal >= amount0Min, InsufficientOutputAmount());
                      (amount0, amount1) = (amount0Optimal, amount1Desired);
                  }
              }
              bool credited = _useTransientBalance(poolKey.token0, poolKey.id0, amount0);
              if (credited) require(msg.value == 0, InvalidMsgVal());
              if (!credited) {
                  if (poolKey.token0 == address(0)) {
                      require(msg.value == amount0, InvalidMsgVal());
                  } else {
                      require(msg.value == 0, InvalidMsgVal());
                      _safeTransferFrom(poolKey.token0, poolKey.id0, amount0);
                  }
              }
              credited = _useTransientBalance(poolKey.token1, poolKey.id1, amount1);
              if (!credited) _safeTransferFrom(poolKey.token1, poolKey.id1, amount1);
              if (supply == 0) {
                  // enforce a single, canonical poolId for any unordered pair:
                  if (poolKey.token0 == address(0)) require(poolKey.id0 == 0, InvalidPoolTokens());
                  require(
                      // 1) two different token contracts/ETH: order by address
                      poolKey.token0 < poolKey.token1
                      // 2) same ERC6909 contract: two distinct, non‑zero IDs in ascending order
                      || (
                          poolKey.token0 == poolKey.token1 && poolKey.id0 != 0 && poolKey.id1 != 0
                              && poolKey.id0 < poolKey.id1
                      ),
                      InvalidPoolTokens()
                  );
                  require(poolKey.swapFee <= MAX_FEE, InvalidSwapFee());
                  liquidity = sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY;
                  require(liquidity != 0, InsufficientLiquidityMinted());
                  _initMint(to, poolId, liquidity);
                  unchecked {
                      pool.supply = liquidity + MINIMUM_LIQUIDITY;
                  }
              } else {
                  liquidity = min(mulDiv(amount0, supply, reserve0), mulDiv(amount1, supply, reserve1));
                  require(liquidity != 0, InsufficientLiquidityMinted());
                  _mint(to, poolId, liquidity);
                  pool.supply += liquidity;
              }
              _update(pool, poolId, amount0 + reserve0, amount1 + reserve1, reserve0, reserve1);
              if (feeOn) pool.kLast = uint256(pool.reserve0) * pool.reserve1;
              emit Mint(poolId, msg.sender, amount0, amount1);
          }
          function removeLiquidity(
              PoolKey calldata poolKey,
              uint256 liquidity,
              uint256 amount0Min,
              uint256 amount1Min,
              address to,
              uint256 deadline
          ) public lock returns (uint256 amount0, uint256 amount1) {
              require(deadline >= block.timestamp, Expired());
              uint256 poolId = _getPoolId(poolKey);
              Pool storage pool = pools[poolId];
              (uint112 reserve0, uint112 reserve1) = (pool.reserve0, pool.reserve1);
              bool feeOn = _mintFee(pool, poolId, reserve0, reserve1);
              amount0 = mulDiv(liquidity, reserve0, pool.supply);
              amount1 = mulDiv(liquidity, reserve1, pool.supply);
              require(amount0 >= amount0Min, InsufficientOutputAmount());
              require(amount1 >= amount1Min, InsufficientOutputAmount());
              _burn(poolId, liquidity);
              unchecked {
                  pool.supply -= liquidity;
              }
              _safeTransfer(poolKey.token0, to, poolKey.id0, amount0);
              _safeTransfer(poolKey.token1, to, poolKey.id1, amount1);
              unchecked {
                  _update(pool, poolId, reserve0 - amount0, reserve1 - amount1, reserve0, reserve1);
              }
              if (feeOn) pool.kLast = uint256(pool.reserve0) * pool.reserve1; // `reserve0` and `reserve1` are up-to-date
              emit Burn(poolId, msg.sender, amount0, amount1, to);
          }
          // ** FACTORY
          event URI(string uri, uint256 indexed coinId);
          function make(address maker, uint256 supply, string calldata uri)
              public
              returns (uint256 coinId)
          {
              coinId =
                  uint256(keccak256(abi.encodePacked(this.make.selector, msg.sender, block.timestamp)));
              _initMint(maker, coinId, supply);
              emit URI(uri, coinId);
          }
          function makeLiquid(
              address maker,
              address liqTo,
              uint256 mkrAmt,
              uint256 liqAmt,
              uint256 swapFee,
              string calldata uri
          ) public payable returns (uint256 coinId, uint256 poolId, uint256 liquidity) {
              require(swapFee <= MAX_FEE, InvalidSwapFee());
              require(liqAmt <= type(uint256).max - mkrAmt, Overflow());
              coinId = uint256(
                  keccak256(abi.encodePacked(this.makeLiquid.selector, msg.sender, block.timestamp))
              );
              if (mkrAmt != 0) _initMint(maker, coinId, mkrAmt);
              emit URI(uri, coinId);
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(m, 0)
                  mstore(add(m, 0x20), coinId)
                  mstore(add(m, 0x40), 0)
                  mstore(add(m, 0x60), address())
                  mstore(add(m, 0x80), swapFee)
                  poolId := keccak256(m, 0xa0)
              }
              Pool storage pool = pools[poolId];
              bool feeOn;
              assembly ("memory-safe") {
                  feeOn := iszero(iszero(sload(0x20)))
              }
              liquidity = sqrt(msg.value * liqAmt) - MINIMUM_LIQUIDITY;
              require(liquidity != 0, InsufficientLiquidityMinted());
              _initMint(liqTo, poolId, liquidity);
              unchecked {
                  pool.supply = liquidity + MINIMUM_LIQUIDITY;
              }
              _update(pool, poolId, msg.value, liqAmt, 0, 0);
              if (feeOn) pool.kLast = msg.value * liqAmt;
              emit Mint(poolId, msg.sender, msg.value, liqAmt);
          }
          // ** TRANSIENT
          receive() external payable {
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(0x00, caller())
                  mstore(0x20, 0)
                  mstore(0x40, 0)
                  let slot := keccak256(0x00, 0x60)
                  tstore(slot, add(tload(slot), callvalue()))
                  mstore(0x40, m)
              }
          }
          function deposit(address token, uint256 id, uint256 amount) public payable {
              require(msg.value == (token == address(0) ? amount : 0), InvalidMsgVal());
              if (token != address(0)) _safeTransferFrom(token, id, amount);
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(0x00, caller())
                  mstore(0x20, token)
                  mstore(0x40, id)
                  let slot := keccak256(0x00, 0x60)
                  tstore(slot, add(tload(slot), amount))
                  mstore(0x40, m)
              }
          }
          function _getTransientBalance(address token, uint256 id) internal returns (uint256 bal) {
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(0x00, caller())
                  mstore(0x20, token)
                  mstore(0x40, id)
                  let slot := keccak256(0x00, 0x60)
                  bal := tload(slot)
                  if bal { tstore(slot, 0) }
                  mstore(0x40, m)
              }
          }
          function _useTransientBalance(address token, uint256 id, uint256 amount)
              internal
              returns (bool credited)
          {
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(0x00, caller())
                  mstore(0x20, token)
                  mstore(0x40, id)
                  let slot := keccak256(0x00, 0x60)
                  let bal := tload(slot)
                  if iszero(lt(bal, amount)) {
                      tstore(slot, sub(bal, amount))
                      credited := 1
                  }
                  mstore(0x40, m)
              }
          }
          function recoverTransientBalance(address token, uint256 id, address to)
              public
              lock
              returns (uint256 amount)
          {
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  mstore(0x00, caller())
                  mstore(0x20, token)
                  mstore(0x40, id)
                  let slot := keccak256(0x00, 0x60)
                  amount := tload(slot)
                  if amount { tstore(slot, 0) }
                  mstore(0x40, m)
              }
              if (amount != 0) _safeTransfer(token, to, id, amount);
          }
          // ** GETTERS
          function _getPoolId(PoolKey calldata poolKey) internal pure returns (uint256 poolId) {
              assembly ("memory-safe") {
                  let m := mload(0x40)
                  calldatacopy(m, poolKey, 0xa0)
                  poolId := keccak256(m, 0xa0)
              }
          }
          function _getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut, uint96 swapFee)
              internal
              pure
              returns (uint256 amountOut)
          {
              uint256 amountInWithFee = amountIn * (10000 - swapFee);
              uint256 numerator = amountInWithFee * reserveOut;
              uint256 denominator = (reserveIn * 10000) + amountInWithFee;
              return numerator / denominator;
          }
          function _getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut, uint96 swapFee)
              internal
              pure
              returns (uint256 amountIn)
          {
              uint256 numerator = reserveIn * amountOut * 10000;
              uint256 denominator = (reserveOut - amountOut) * (10000 - swapFee);
              return (numerator / denominator) + 1;
          }
          // ** PROTOCOL FEES
          error Unauthorized();
          function setFeeTo(address feeTo) public payable {
              assembly ("memory-safe") {
                  if iszero(eq(caller(), sload(0x00))) {
                      mstore(0x00, 0x82b42900) // `Unauthorized()`
                      revert(0x1c, 0x04)
                  }
                  sstore(0x20, feeTo)
              }
          }
          function setFeeToSetter(address feeToSetter) public payable {
              assembly ("memory-safe") {
                  if iszero(eq(caller(), sload(0x00))) {
                      mstore(0x00, 0x82b42900) // `Unauthorized()`
                      revert(0x1c, 0x04)
                  }
                  sstore(0x00, feeToSetter)
              }
          }
          // ** BATCH
          function multicall(bytes[] calldata data) public returns (bytes[] memory results) {
              results = new bytes[](data.length);
              for (uint256 i; i != data.length; ++i) {
                  (bool success, bytes memory result) = address(this).delegatecall(data[i]);
                  if (!success) {
                      assembly ("memory-safe") {
                          revert(add(result, 0x20), mload(result))
                      }
                  }
                  results[i] = result;
              }
          }
          // ** COMPRESS
          // Solady (https://github.com/Vectorized/solady/blob/main/src/utils/LibZip)
          fallback() external payable {
              assembly ("memory-safe") {
                  if iszero(calldatasize()) { return(calldatasize(), calldatasize()) }
                  let o := 0
                  let f := not(3)
                  for { let i := 0 } lt(i, calldatasize()) {} {
                      let c := byte(0, xor(add(i, f), calldataload(i)))
                      i := add(i, 1)
                      if iszero(c) {
                          let d := byte(0, xor(add(i, f), calldataload(i)))
                          i := add(i, 1)
                          mstore(o, not(0))
                          if iszero(gt(d, 0x7f)) { calldatacopy(o, calldatasize(), add(d, 1)) }
                          o := add(o, add(and(d, 0x7f), 1))
                          continue
                      }
                      mstore8(o, c)
                      o := add(o, 1)
                  }
                  let success := delegatecall(gas(), address(), 0x00, o, codesize(), 0x00)
                  returndatacopy(0x00, 0x00, returndatasize())
                  if iszero(success) { revert(0x00, returndatasize()) }
                  return(0x00, returndatasize())
              }
          }
      }
      // minimal ZAMM call interface
      interface IZAMMCallee {
          function zammCall(
              uint256 poolId,
              address sender,
              uint256 amount0,
              uint256 amount1,
              bytes calldata data
          ) external;
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.29;
      /// @notice Highly optimized ERC6909 implementation for ZAMM.
      /// @author Modified from Solady (https://github.com/vectorized/solady/blob/main/src/tokens/ERC6909.sol)
      abstract contract ZERC6909 {
          uint256 constant TRANSFER_EVENT_SIGNATURE =
              0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859;
          uint256 constant OPERATOR_SET_EVENT_SIGNATURE =
              0xceb576d9f15e4e200fdb5096d64d5dfd667e16def20c1eefd14256d8e3faa267;
          uint256 constant APPROVAL_EVENT_SIGNATURE =
              0xb3fd5071835887567a0671151121894ddccc2842f1d10bedad13e0d17cace9a7;
          uint256 constant ERC6909_MASTER_SLOT_SEED = 0xedcaa89a82293940;
          function balanceOf(address owner, uint256 id) public view returns (uint256 amount) {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, owner)
                  mstore(0x00, id)
                  amount := sload(keccak256(0x00, 0x40))
              }
          }
          function allowance(address owner, address spender, uint256 id)
              public
              view
              returns (uint256 amount)
          {
              assembly ("memory-safe") {
                  mstore(0x34, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x28, owner)
                  mstore(0x14, spender)
                  mstore(0x00, id)
                  amount := sload(keccak256(0x00, 0x54))
                  mstore(0x34, 0)
              }
          }
          function isOperator(address owner, address spender) public view returns (bool status) {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, owner)
                  mstore(0x00, spender)
                  status := sload(keccak256(0x0c, 0x34))
              }
          }
          function transfer(address to, uint256 id, uint256 amount) public returns (bool) {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, caller())
                  mstore(0x00, id)
                  let fromBalanceSlot := keccak256(0x00, 0x40)
                  let fromBalance := sload(fromBalanceSlot)
                  if gt(amount, fromBalance) {
                      mstore(0x00, 0xf4d678b8)
                      revert(0x1c, 0x04)
                  }
                  sstore(fromBalanceSlot, sub(fromBalance, amount))
                  mstore(0x14, to)
                  mstore(0x00, id)
                  let toBalanceSlot := keccak256(0x00, 0x40)
                  let toBalanceBefore := sload(toBalanceSlot)
                  let toBalanceAfter := add(toBalanceBefore, amount)
                  if lt(toBalanceAfter, toBalanceBefore) {
                      mstore(0x00, 0x89560ca1)
                      revert(0x1c, 0x04)
                  }
                  sstore(toBalanceSlot, toBalanceAfter)
                  mstore(0x00, caller())
                  mstore(0x20, amount)
                  log4(0x00, 0x40, TRANSFER_EVENT_SIGNATURE, caller(), shr(96, shl(96, to)), id)
                  mstore(0x00, 1)
                  return(0x00, 0x20)
              }
          }
          function transferFrom(address from, address to, uint256 id, uint256 amount)
              public
              returns (bool)
          {
              assembly ("memory-safe") {
                  mstore(0x34, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x28, from)
                  mstore(0x14, caller())
                  if iszero(sload(keccak256(0x20, 0x34))) {
                      mstore(0x00, id)
                      let allowanceSlot := keccak256(0x00, 0x54)
                      let allowance_ := sload(allowanceSlot)
                      if add(allowance_, 1) {
                          if gt(amount, allowance_) {
                              mstore(0x00, 0xdeda9030)
                              revert(0x1c, 0x04)
                          }
                          sstore(allowanceSlot, sub(allowance_, amount))
                      }
                  }
                  mstore(0x14, id)
                  let fromBalanceSlot := keccak256(0x14, 0x40)
                  let fromBalance := sload(fromBalanceSlot)
                  if gt(amount, fromBalance) {
                      mstore(0x00, 0xf4d678b8)
                      revert(0x1c, 0x04)
                  }
                  sstore(fromBalanceSlot, sub(fromBalance, amount))
                  mstore(0x28, to)
                  mstore(0x14, id)
                  let toBalanceSlot := keccak256(0x14, 0x40)
                  let toBalanceBefore := sload(toBalanceSlot)
                  let toBalanceAfter := add(toBalanceBefore, amount)
                  if lt(toBalanceAfter, toBalanceBefore) {
                      mstore(0x00, 0x89560ca1)
                      revert(0x1c, 0x04)
                  }
                  sstore(toBalanceSlot, toBalanceAfter)
                  mstore(0x00, caller())
                  mstore(0x20, amount)
                  // forgefmt: disable-next-line
                  log4(0x00, 0x40, TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, from)), shr(96, shl(96, to)), id)
                  mstore(0x34, 0)
                  mstore(0x00, 1)
                  return(0x00, 0x20)
              }
          }
          function approve(address spender, uint256 id, uint256 amount) public returns (bool) {
              assembly ("memory-safe") {
                  mstore(0x34, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x28, caller())
                  mstore(0x14, spender)
                  mstore(0x00, id)
                  sstore(keccak256(0x00, 0x54), amount)
                  mstore(0x00, amount)
                  log4(0x00, 0x20, APPROVAL_EVENT_SIGNATURE, caller(), shr(96, mload(0x20)), id)
                  mstore(0x34, 0)
                  mstore(0x00, 1)
                  return(0x00, 0x20)
              }
          }
          function setOperator(address operator, bool approved) public returns (bool) {
              assembly ("memory-safe") {
                  let approvedCleaned := iszero(iszero(approved))
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, caller())
                  mstore(0x00, operator)
                  sstore(keccak256(0x0c, 0x34), approvedCleaned)
                  mstore(0x20, approvedCleaned)
                  log3(0x20, 0x20, OPERATOR_SET_EVENT_SIGNATURE, caller(), shr(96, mload(0x0c)))
                  mstore(0x00, 1)
                  return(0x00, 0x20)
              }
          }
          function supportsInterface(bytes4 interfaceId) public pure returns (bool result) {
              assembly ("memory-safe") {
                  let s := shr(224, interfaceId)
                  result := or(eq(s, 0x01ffc9a7), eq(s, 0x0f632fb3))
              }
          }
          function _initMint(address to, uint256 id, uint256 amount) internal {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, to)
                  mstore(0x00, id)
                  sstore(keccak256(0x00, 0x40), amount)
                  mstore(0x00, caller())
                  mstore(0x20, amount)
                  log4(0x00, 0x40, TRANSFER_EVENT_SIGNATURE, 0, shr(96, shl(96, to)), id)
              }
          }
          function _mint(address to, uint256 id, uint256 amount) internal {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, to)
                  mstore(0x00, id)
                  let toBalanceSlot := keccak256(0x00, 0x40)
                  let toBalanceBefore := sload(toBalanceSlot)
                  let toBalanceAfter := add(toBalanceBefore, amount)
                  if lt(toBalanceAfter, toBalanceBefore) {
                      mstore(0x00, 0x89560ca1)
                      revert(0x1c, 0x04)
                  }
                  sstore(toBalanceSlot, toBalanceAfter)
                  mstore(0x00, caller())
                  mstore(0x20, amount)
                  log4(0x00, 0x40, TRANSFER_EVENT_SIGNATURE, 0, shr(96, shl(96, to)), id)
              }
          }
          function _burn(uint256 id, uint256 amount) internal {
              assembly ("memory-safe") {
                  mstore(0x20, ERC6909_MASTER_SLOT_SEED)
                  mstore(0x14, caller())
                  mstore(0x00, id)
                  let fromBalanceSlot := keccak256(0x00, 0x40)
                  let fromBalance := sload(fromBalanceSlot)
                  if gt(amount, fromBalance) {
                      mstore(0x00, 0xf4d678b8)
                      revert(0x1c, 0x04)
                  }
                  sstore(fromBalanceSlot, sub(fromBalance, amount))
                  mstore(0x00, caller())
                  mstore(0x20, amount)
                  log4(0x00, 0x40, TRANSFER_EVENT_SIGNATURE, shr(96, shl(96, caller())), 0, id)
              }
          }
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.29;
      // Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/FixedPointMathLib.sol)
      /// @dev Returns the minimum of `x` and `y`.
      function min(uint256 x, uint256 y) pure returns (uint256 z) {
          assembly ("memory-safe") {
              z := xor(x, mul(xor(x, y), lt(y, x)))
          }
      }
      /// @dev Returns `floor(x * y / d)`.
      /// Reverts if `x * y` overflows, or `d` is zero.
      function mulDiv(uint256 x, uint256 y, uint256 d) pure returns (uint256 z) {
          assembly ("memory-safe") {
              z := mul(x, y)
              if iszero(mul(or(iszero(x), eq(div(z, x), y)), d)) {
                  mstore(0x00, 0xad251c27)
                  revert(0x1c, 0x04)
              }
              z := div(z, d)
          }
      }
      /// @dev Returns the square root of `x`, rounded down.
      function sqrt(uint256 x) pure returns (uint256 z) {
          assembly ("memory-safe") {
              z := 181
              let r := shl(7, lt(0xffffffffffffffffffffffffffffffffff, x))
              r := or(r, shl(6, lt(0xffffffffffffffffff, shr(r, x))))
              r := or(r, shl(5, lt(0xffffffffff, shr(r, x))))
              r := or(r, shl(4, lt(0xffffff, shr(r, x))))
              z := shl(shr(1, r), z)
              z := shr(18, mul(z, add(shr(r, x), 65536)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := shr(1, add(z, div(x, z)))
              z := sub(z, lt(div(x, z), z))
          }
      }
      // Modified from Uniswap V2 (https://github.com/Uniswap/v2-core/blob/master/contracts/libraries/UQ112x112.sol)
      // Licensed GPL-3.0
      /// @dev Encode a uint112 as a UQ112x112.
      function encode(uint112 y) pure returns (uint224 z) {
          unchecked {
              z = uint224(y) * 2 ** 112;
          }
      }
      /// @dev Divide a UQ112x112 by a uint112, returning a UQ112x112.
      function uqdiv(uint224 x, uint112 y) pure returns (uint224 z) {
          unchecked {
              z = x / uint224(y);
          }
      }
      // SPDX-License-Identifier: MIT
      pragma solidity ^0.8.29;
      // Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
      /// @dev Sends `amount` (in wei) ETH to `to`.
      function safeTransferETH(address to, uint256 amount) {
          assembly ("memory-safe") {
              if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                  mstore(0x00, 0xb12d13eb)
                  revert(0x1c, 0x04)
              }
          }
      }
      /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
      /// Reverts upon failure.
      function safeTransfer(address token, address to, uint256 amount) {
          assembly ("memory-safe") {
              mstore(0x14, to)
              mstore(0x34, amount)
              mstore(0x00, 0xa9059cbb000000000000000000000000)
              let success := call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
              if iszero(and(eq(mload(0x00), 1), success)) {
                  if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                      mstore(0x00, 0x90b8ec18)
                      revert(0x1c, 0x04)
                  }
              }
              mstore(0x34, 0)
          }
      }
      /// @dev Sends `amount` of ERC20 `token` from caller to `this`.
      /// Reverts upon failure.
      ///
      /// The caller account must have at least `amount` approved for
      /// the current contract to manage.
      function safeTransferFrom(address token, uint256 amount) {
          assembly ("memory-safe") {
              let m := mload(0x40)
              mstore(0x60, amount)
              mstore(0x40, address())
              mstore(0x2c, shl(96, caller()))
              mstore(0x0c, 0x23b872dd000000000000000000000000)
              let success := call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
              if iszero(and(eq(mload(0x00), 1), success)) {
                  if iszero(lt(or(iszero(extcodesize(token)), returndatasize()), success)) {
                      mstore(0x00, 0x7939f424)
                      revert(0x1c, 0x04)
                  }
              }
              mstore(0x60, 0)
              mstore(0x40, m)
          }
      }