@zarclays/zswap-trident
Version:
271 lines • 149 kB
JSON
{
"address": "0x752Dc00ABa9c930c84aC81D288dB5E2a02Afe633",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_masterDeployer",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "InvalidTokenOrder",
"type": "error"
},
{
"inputs": [],
"name": "UnauthorisedDeployer",
"type": "error"
},
{
"inputs": [],
"name": "ZeroAddress",
"type": "error"
},
{
"inputs": [],
"name": "bytecodeHash",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token0",
"type": "address"
},
{
"internalType": "address",
"name": "token1",
"type": "address"
},
{
"internalType": "uint256",
"name": "swapFee",
"type": "uint256"
},
{
"internalType": "bool",
"name": "twapSupport",
"type": "bool"
}
],
"name": "calculatePoolAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "configAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes",
"name": "_deployData",
"type": "bytes"
}
],
"name": "deployPool",
"outputs": [
{
"internalType": "address",
"name": "pool",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getDeployData",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
},
{
"internalType": "contract IMasterDeployer",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token0",
"type": "address"
},
{
"internalType": "address",
"name": "token1",
"type": "address"
},
{
"internalType": "uint256",
"name": "startIndex",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "count",
"type": "uint256"
}
],
"name": "getPools",
"outputs": [
{
"internalType": "address[]",
"name": "pairPools",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "masterDeployer",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "pools",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "token0",
"type": "address"
},
{
"internalType": "address",
"name": "token1",
"type": "address"
}
],
"name": "poolsCount",
"outputs": [
{
"internalType": "uint256",
"name": "count",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
],
"transactionHash": "0x27e6cf1cc61fd2f00b29496372af116609b8513df830e3d48ffcd96812d1605d",
"receipt": {
"to": null,
"from": "0xf87BC5535602077d340806D71f805EA9907a843D",
"contractAddress": "0x752Dc00ABa9c930c84aC81D288dB5E2a02Afe633",
"transactionIndex": 9,
"gasUsed": "4744985",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000008000000000000000000000000000000000000800000001000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000080000010000000000200000000000000000000000000000000000000000000000000000000000004000000000000000000001000000000000000000000000000000100000000000000000000000000080000010000000000000000000000000000000000000100000",
"blockHash": "0xa90f760535142a71b833d4073cea47f1c0844548991eaaea86dcbb729b45517a",
"transactionHash": "0x27e6cf1cc61fd2f00b29496372af116609b8513df830e3d48ffcd96812d1605d",
"logs": [
{
"transactionIndex": 9,
"blockNumber": 13310769,
"transactionHash": "0x27e6cf1cc61fd2f00b29496372af116609b8513df830e3d48ffcd96812d1605d",
"address": "0x0000000000000000000000000000000000001010",
"topics": [
"0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63",
"0x0000000000000000000000000000000000000000000000000000000000001010",
"0x000000000000000000000000f87bc5535602077d340806d71f805ea9907a843d",
"0x0000000000000000000000006e275592bd4af7192e9016b7c80d0db0a3ba190a"
],
"data": "0x00000000000000000000000000000000000000000000004d2af7ef3f6310c00000000000000000000000000000000000000000000000671c1dcab7e417d240000000000000000000000000000000000000000000021d685fa613742a478c04190000000000000000000000000000000000000000000066cef2d2c8a4b4c180000000000000000000000000000000000000000000021d68acd10b6369aa9cc419",
"logIndex": 20,
"blockHash": "0xa90f760535142a71b833d4073cea47f1c0844548991eaaea86dcbb729b45517a"
}
],
"blockNumber": 13310769,
"cumulativeGasUsed": "6041169",
"status": 1,
"byzantium": true
},
"args": [
"0x281BD3A3F96ae7C96049493A7BA9449Df2C5B0FE"
],
"numDeployments": 3,
"solcInputHash": "7d1323ab452b40d0444e8e5feeeaadf3",
"metadata": "{\"compiler\":{\"version\":\"0.8.10+commit.fc410830\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_masterDeployer\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidTokenOrder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorisedDeployer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"bytecodeHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token1\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"swapFee\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"twapSupport\",\"type\":\"bool\"}],\"name\":\"calculatePoolAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"configAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"_deployData\",\"type\":\"bytes\"}],\"name\":\"deployPool\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getDeployData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"},{\"internalType\":\"contract IMasterDeployer\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token1\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"name\":\"getPools\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"pairPools\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"masterDeployer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"pools\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token0\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"token1\",\"type\":\"address\"}],\"name\":\"poolsCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"count\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Mudit Gupta.\",\"errors\":{\"UnauthorisedDeployer()\":[{\"details\":\"Custom Errors\"}]},\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"Contract for deploying Trident exchange Constant Product Pool with configurations.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/pool/constant-product/ConstantProductPoolFactory.sol\":\"ConstantProductPoolFactory\"},\"evmVersion\":\"london\",\"libraries\":{\":__CACHE_BREAKER__\":\"0x00000000d41867734bbee4c6863d9255b2b06ac1\"},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":999999},\"remappings\":[]},\"sources\":{\"@rari-capital/solmate/src/tokens/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol)\\n/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)\\n/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.\\nabstract contract ERC20 {\\n /*///////////////////////////////////////////////////////////////\\n EVENTS\\n //////////////////////////////////////////////////////////////*/\\n\\n event Transfer(address indexed from, address indexed to, uint256 amount);\\n\\n event Approval(address indexed owner, address indexed spender, uint256 amount);\\n\\n /*///////////////////////////////////////////////////////////////\\n METADATA STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n string public name;\\n\\n string public symbol;\\n\\n uint8 public immutable decimals;\\n\\n /*///////////////////////////////////////////////////////////////\\n ERC20 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n uint256 public totalSupply;\\n\\n mapping(address => uint256) public balanceOf;\\n\\n mapping(address => mapping(address => uint256)) public allowance;\\n\\n /*///////////////////////////////////////////////////////////////\\n EIP-2612 STORAGE\\n //////////////////////////////////////////////////////////////*/\\n\\n bytes32 public constant PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n uint256 internal immutable INITIAL_CHAIN_ID;\\n\\n bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;\\n\\n mapping(address => uint256) public nonces;\\n\\n /*///////////////////////////////////////////////////////////////\\n CONSTRUCTOR\\n //////////////////////////////////////////////////////////////*/\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n uint8 _decimals\\n ) {\\n name = _name;\\n symbol = _symbol;\\n decimals = _decimals;\\n\\n INITIAL_CHAIN_ID = block.chainid;\\n INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();\\n }\\n\\n /*///////////////////////////////////////////////////////////////\\n ERC20 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function approve(address spender, uint256 amount) public virtual returns (bool) {\\n allowance[msg.sender][spender] = amount;\\n\\n emit Approval(msg.sender, spender, amount);\\n\\n return true;\\n }\\n\\n function transfer(address to, uint256 amount) public virtual returns (bool) {\\n balanceOf[msg.sender] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(msg.sender, to, amount);\\n\\n return true;\\n }\\n\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) public virtual returns (bool) {\\n uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.\\n\\n if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;\\n\\n balanceOf[from] -= amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n return true;\\n }\\n\\n /*///////////////////////////////////////////////////////////////\\n EIP-2612 LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(deadline >= block.timestamp, \\\"PERMIT_DEADLINE_EXPIRED\\\");\\n\\n // Unchecked because the only math done is incrementing\\n // the owner's nonce which cannot realistically overflow.\\n unchecked {\\n bytes32 digest = keccak256(\\n abi.encodePacked(\\n \\\"\\\\x19\\\\x01\\\",\\n DOMAIN_SEPARATOR(),\\n keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))\\n )\\n );\\n\\n address recoveredAddress = ecrecover(digest, v, r, s);\\n\\n require(recoveredAddress != address(0) && recoveredAddress == owner, \\\"INVALID_SIGNER\\\");\\n\\n allowance[recoveredAddress][spender] = value;\\n }\\n\\n emit Approval(owner, spender, value);\\n }\\n\\n function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {\\n return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();\\n }\\n\\n function computeDomainSeparator() internal view virtual returns (bytes32) {\\n return\\n keccak256(\\n abi.encode(\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"),\\n keccak256(bytes(name)),\\n keccak256(\\\"1\\\"),\\n block.chainid,\\n address(this)\\n )\\n );\\n }\\n\\n /*///////////////////////////////////////////////////////////////\\n INTERNAL MINT/BURN LOGIC\\n //////////////////////////////////////////////////////////////*/\\n\\n function _mint(address to, uint256 amount) internal virtual {\\n totalSupply += amount;\\n\\n // Cannot overflow because the sum of all user\\n // balances can't exceed the max uint256 value.\\n unchecked {\\n balanceOf[to] += amount;\\n }\\n\\n emit Transfer(address(0), to, amount);\\n }\\n\\n function _burn(address from, uint256 amount) internal virtual {\\n balanceOf[from] -= amount;\\n\\n // Cannot underflow because a user's balance\\n // will never be larger than the total supply.\\n unchecked {\\n totalSupply -= amount;\\n }\\n\\n emit Transfer(from, address(0), amount);\\n }\\n}\\n\",\"keccak256\":\"0x698cdbf614109fafc2bf00057b60715fa3aba9dad447c42f4f8b749ae16ce84f\",\"license\":\"AGPL-3.0-only\"},\"@rari-capital/solmate/src/utils/ReentrancyGuard.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-only\\npragma solidity >=0.8.0;\\n\\n/// @notice Gas optimized reentrancy protection for smart contracts.\\n/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol)\\n/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)\\nabstract contract ReentrancyGuard {\\n uint256 private reentrancyStatus = 1;\\n\\n modifier nonReentrant() {\\n require(reentrancyStatus == 1, \\\"REENTRANCY\\\");\\n\\n reentrancyStatus = 2;\\n\\n _;\\n\\n reentrancyStatus = 1;\\n }\\n}\\n\",\"keccak256\":\"0x37da48458a348878d8db5b58367d734e340b9172ef947df430027638fc45a015\",\"license\":\"AGPL-3.0-only\"},\"contracts/abstract/PoolDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later-only\\n\\npragma solidity >=0.8.0;\\n\\n/// @dev Custom Errors\\nerror UnauthorisedDeployer();\\nerror ZeroAddress();\\nerror InvalidTokenOrder();\\n\\n/// @notice Trident pool deployer for whitelisted template factories.\\n/// @author Mudit Gupta.\\nabstract contract PoolDeployer {\\n address public immutable masterDeployer;\\n\\n mapping(address => mapping(address => address[])) public pools;\\n mapping(bytes32 => address) public configAddress;\\n\\n modifier onlyMaster() {\\n if (msg.sender != masterDeployer) revert UnauthorisedDeployer();\\n _;\\n }\\n\\n constructor(address _masterDeployer) {\\n if (_masterDeployer == address(0)) revert ZeroAddress();\\n masterDeployer = _masterDeployer;\\n }\\n\\n function _registerPool(\\n address pool,\\n address[] memory tokens,\\n bytes32 salt\\n ) internal onlyMaster {\\n // Store the address of the deployed contract.\\n configAddress[salt] = pool;\\n // Attacker used underflow, it was not very effective. poolimon!\\n // null token array would cause deployment to fail via out of bounds memory axis/gas limit.\\n unchecked {\\n for (uint256 i; i < tokens.length - 1; ++i) {\\n if (tokens[i] >= tokens[i + 1]) revert InvalidTokenOrder();\\n for (uint256 j = i + 1; j < tokens.length; ++j) {\\n pools[tokens[i]][tokens[j]].push(pool);\\n pools[tokens[j]][tokens[i]].push(pool);\\n }\\n }\\n }\\n }\\n\\n function poolsCount(address token0, address token1) external view returns (uint256 count) {\\n count = pools[token0][token1].length;\\n }\\n\\n function getPools(\\n address token0,\\n address token1,\\n uint256 startIndex,\\n uint256 count\\n ) external view returns (address[] memory pairPools) {\\n pairPools = new address[](count);\\n for (uint256 i = 0; i < count; i++) {\\n pairPools[i] = pools[token0][token1][startIndex + i];\\n }\\n }\\n}\\n\",\"keccak256\":\"0x8e62e4204fe089b02a80330804cdc69aa3d6ae91d2ea7d371683ebf4aeacb817\",\"license\":\"GPL-3.0-or-later-only\"},\"contracts/interfaces/IBentoBoxMinimal.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\nimport \\\"../libraries/RebaseLibrary.sol\\\";\\n\\n/// @notice Minimal BentoBox vault interface.\\n/// @dev `token` is aliased as `address` from `IERC20` for simplicity.\\ninterface IBentoBoxMinimal {\\n /// @notice Balance per ERC-20 token per account in shares.\\n function balanceOf(address, address) external view returns (uint256);\\n\\n /// @dev Helper function to represent an `amount` of `token` in shares.\\n /// @param token The ERC-20 token.\\n /// @param amount The `token` amount.\\n /// @param roundUp If the result `share` should be rounded up.\\n /// @return share The token amount represented in shares.\\n function toShare(\\n address token,\\n uint256 amount,\\n bool roundUp\\n ) external view returns (uint256 share);\\n\\n /// @dev Helper function to represent shares back into the `token` amount.\\n /// @param token The ERC-20 token.\\n /// @param share The amount of shares.\\n /// @param roundUp If the result should be rounded up.\\n /// @return amount The share amount back into native representation.\\n function toAmount(\\n address token,\\n uint256 share,\\n bool roundUp\\n ) external view returns (uint256 amount);\\n\\n /// @notice Registers this contract so that users can approve it for BentoBox.\\n function registerProtocol() external;\\n\\n /// @notice Deposit an amount of `token` represented in either `amount` or `share`.\\n /// @param token The ERC-20 token to deposit.\\n /// @param from which account to pull the tokens.\\n /// @param to which account to push the tokens.\\n /// @param amount Token amount in native representation to deposit.\\n /// @param share Token amount represented in shares to deposit. Takes precedence over `amount`.\\n /// @return amountOut The amount deposited.\\n /// @return shareOut The deposited amount represented in shares.\\n function deposit(\\n address token,\\n address from,\\n address to,\\n uint256 amount,\\n uint256 share\\n ) external payable returns (uint256 amountOut, uint256 shareOut);\\n\\n /// @notice Withdraws an amount of `token` from a user account.\\n /// @param token_ The ERC-20 token to withdraw.\\n /// @param from which user to pull the tokens.\\n /// @param to which user to push the tokens.\\n /// @param amount of tokens. Either one of `amount` or `share` needs to be supplied.\\n /// @param share Like above, but `share` takes precedence over `amount`.\\n function withdraw(\\n address token_,\\n address from,\\n address to,\\n uint256 amount,\\n uint256 share\\n ) external returns (uint256 amountOut, uint256 shareOut);\\n\\n /// @notice Transfer shares from a user account to another one.\\n /// @param token The ERC-20 token to transfer.\\n /// @param from which user to pull the tokens.\\n /// @param to which user to push the tokens.\\n /// @param share The amount of `token` in shares.\\n function transfer(\\n address token,\\n address from,\\n address to,\\n uint256 share\\n ) external;\\n\\n /// @dev Reads the Rebase `totals`from storage for a given token\\n function totals(address token) external view returns (Rebase memory total);\\n\\n /// @dev Approves users' BentoBox assets to a \\\"master\\\" contract.\\n function setMasterContractApproval(\\n address user,\\n address masterContract,\\n bool approved,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n function harvest(\\n address token,\\n bool balance,\\n uint256 maxChangeAmount\\n ) external;\\n}\\n\",\"keccak256\":\"0xe9dfcff95da3b487ff37f646aef14a998a36f90122fd5693096b5e3b14ea09af\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/IConstantProductPoolFactory.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\nimport \\\"./IMasterDeployer.sol\\\";\\n\\ninterface IConstantProductPoolFactory {\\n function getDeployData() external view returns (bytes memory, IMasterDeployer);\\n}\\n\",\"keccak256\":\"0xf733168896197b23ffeee83630f9c90fb5e3c2ec6613de0f844e451f45985800\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/IMasterDeployer.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool deployer interface.\\ninterface IMasterDeployer {\\n function barFee() external view returns (uint256);\\n\\n function barFeeTo() external view returns (address);\\n\\n function bento() external view returns (address);\\n\\n function migrator() external view returns (address);\\n\\n function pools(address pool) external view returns (bool);\\n\\n function deployPool(address factory, bytes calldata deployData) external returns (address);\\n}\\n\",\"keccak256\":\"0x91c23deb7e4372faa35a0ae4ef6ccd684049aea7b2c75cf63009b28591b91cbc\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/IPool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.5.0;\\npragma experimental ABIEncoderV2;\\n\\n/// @notice Trident pool interface.\\ninterface IPool {\\n /// @notice Executes a swap from one token to another.\\n /// @dev The input tokens must've already been sent to the pool.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\\n function swap(bytes calldata data) external returns (uint256 finalAmountOut);\\n\\n /// @notice Executes a swap from one token to another with a callback.\\n /// @dev This function allows borrowing the output tokens and sending the input tokens in the callback.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return finalAmountOut The amount of output tokens that were sent to the user.\\n function flashSwap(bytes calldata data) external returns (uint256 finalAmountOut);\\n\\n /// @notice Mints liquidity tokens.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return liquidity The amount of liquidity tokens that were minted for the user.\\n function mint(bytes calldata data) external returns (uint256 liquidity);\\n\\n /// @notice Burns liquidity tokens.\\n /// @dev The input LP tokens must've already been sent to the pool.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return withdrawnAmounts The amount of various output tokens that were sent to the user.\\n function burn(bytes calldata data) external returns (TokenAmount[] memory withdrawnAmounts);\\n\\n /// @notice Burns liquidity tokens for a single output token.\\n /// @dev The input LP tokens must've already been sent to the pool.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return amountOut The amount of output tokens that were sent to the user.\\n function burnSingle(bytes calldata data) external returns (uint256 amountOut);\\n\\n /// @return A unique identifier for the pool type.\\n function poolIdentifier() external pure returns (bytes32);\\n\\n /// @return An array of tokens supported by the pool.\\n function getAssets() external view returns (address[] memory);\\n\\n /// @notice Simulates a trade and returns the expected output.\\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return finalAmountOut The amount of output tokens that will be sent to the user if the trade is executed.\\n function getAmountOut(bytes calldata data) external view returns (uint256 finalAmountOut);\\n\\n /// @notice Simulates a trade and returns the expected output.\\n /// @dev The pool does not need to include a trade simulator directly in itself - it can use a library.\\n /// @param data ABI-encoded params that the pool requires.\\n /// @return finalAmountIn The amount of input tokens that are required from the user if the trade is executed.\\n function getAmountIn(bytes calldata data) external view returns (uint256 finalAmountIn);\\n\\n /// @dev This event must be emitted on all swaps.\\n event Swap(address indexed recipient, address indexed tokenIn, address indexed tokenOut, uint256 amountIn, uint256 amountOut);\\n\\n /// @dev This struct frames output tokens for burns.\\n struct TokenAmount {\\n address token;\\n uint256 amount;\\n }\\n}\\n\",\"keccak256\":\"0xa6f92ccb525b018c0c209819640e8d746f1134b4c4d9acd4f22d3e170323f1fa\",\"license\":\"GPL-3.0-or-later\"},\"contracts/interfaces/ITridentCallee.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident pool callback interface.\\ninterface ITridentCallee {\\n function tridentSwapCallback(bytes calldata data) external;\\n\\n function tridentMintCallback(bytes calldata data) external;\\n}\\n\",\"keccak256\":\"0x256e838362a3064201b37b3b7c08bc1421b173a6fea633176123f0b827b868c9\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/RebaseLibrary.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity ^0.8;\\n\\nstruct Rebase {\\n uint128 elastic;\\n uint128 base;\\n}\\n\\n/// @notice A rebasing library\\nlibrary RebaseLibrary {\\n /// @notice Calculates the base value in relationship to `elastic` and `total`.\\n function toBase(Rebase memory total, uint256 elastic) internal pure returns (uint256 base) {\\n if (total.elastic == 0) {\\n base = elastic;\\n } else {\\n base = (elastic * total.base) / total.elastic;\\n }\\n }\\n\\n /// @notice Calculates the elastic value in relationship to `base` and `total`.\\n function toElastic(Rebase memory total, uint256 base) internal pure returns (uint256 elastic) {\\n if (total.base == 0) {\\n elastic = base;\\n } else {\\n elastic = (base * total.elastic) / total.base;\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa83360497e7e2a04332211832a8ceb41ef0301892fcf1b17174d7d4466782d44\",\"license\":\"GPL-3.0-or-later\"},\"contracts/libraries/TridentMath.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\n/// @notice Trident sqrt helper library.\\nlibrary TridentMath {\\n /// @dev Modified from Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)\\n function sqrt(uint256 x) internal pure returns (uint256 z) {\\n assembly {\\n // This segment is to get a reasonable initial estimate for the Babylonian method.\\n // If the initial estimate is bad, the number of correct bits increases ~linearly\\n // each iteration instead of ~quadratically.\\n // The idea is to get z*z*y within a small factor of x.\\n // More iterations here gets y in a tighter range. Currently, we will have\\n // y in [256, 256*2^16). We ensure y>= 256 so that the relative difference\\n // between y and y+1 is small. If x < 256 this is not possible, but those cases\\n // are easy enough to verify exhaustively.\\n z := 181 // The 'correct' value is 1, but this saves a multiply later\\n let y := x\\n // Note that we check y>= 2^(k + 8) but shift right by k bits each branch,\\n // this is to ensure that if x >= 256, then y >= 256.\\n if iszero(lt(y, 0x10000000000000000000000000000000000)) {\\n y := shr(128, y)\\n z := shl(64, z)\\n }\\n if iszero(lt(y, 0x1000000000000000000)) {\\n y := shr(64, y)\\n z := shl(32, z)\\n }\\n if iszero(lt(y, 0x10000000000)) {\\n y := shr(32, y)\\n z := shl(16, z)\\n }\\n if iszero(lt(y, 0x1000000)) {\\n y := shr(16, y)\\n z := shl(8, z)\\n }\\n // Now, z*z*y <= x < z*z*(y+1), and y <= 2^(16+8),\\n // and either y >= 256, or x < 256.\\n // Correctness can be checked exhaustively for x < 256, so we assume y >= 256.\\n // Then z*sqrt(y) is within sqrt(257)/sqrt(256) of sqrt(x), or about 20bps.\\n\\n // For s in the range [1/256, 256], the estimate f(s) = (181/1024) * (s+1)\\n // is in the range (1/2.84 * sqrt(s), 2.84 * sqrt(s)), with largest error when s=1\\n // and when s = 256 or 1/256. Since y is in [256, 256*2^16), let a = y/65536, so\\n // that a is in [1/256, 256). Then we can estimate sqrt(y) as\\n // sqrt(65536) * 181/1024 * (a + 1) = 181/4 * (y + 65536)/65536 = 181 * (y + 65536)/2^18\\n // There is no overflow risk here since y < 2^136 after the first branch above.\\n z := shr(18, mul(z, add(y, 65536))) // A multiply is saved from the initial z := 181\\n\\n // Given the worst case multiplicative error of 2.84 above, 7 iterations should be enough.\\n // Possibly with a quadratic/cubic polynomial above we could get 4-6.\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n z := shr(1, add(z, div(x, z)))\\n\\n // See https://en.wikipedia.org/wiki/Integer_square_root#Using_only_integer_division.\\n // If x+1 is a perfect square, the Babylonian method cycles between\\n // floor(sqrt(x)) and ceil(sqrt(x)). This check ensures we return floor.\\n // Since this case is rare, we choose to save gas on the assignment and\\n // repeat division in the rare case.\\n // If you don't care whether floor or ceil is returned, you can skip this.\\n if lt(div(x, z), z) {\\n z := div(x, z)\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xe46dce6bcd88a42bc841147b5e4df7176491d178b6c8af7a9525b36c0b826738\",\"license\":\"GPL-3.0-or-later\"},\"contracts/pool/constant-product/ConstantProductPool.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0-or-later\\n\\npragma solidity >=0.8.0;\\n\\nimport {ERC20} from \\\"@rari-capital/solmate/src/tokens/ERC20.sol\\\";\\nimport {ReentrancyGuard} from \\\"@rari-capital/solmate/src/utils/ReentrancyGuard.sol\\\";\\n\\nimport {IBentoBoxMinimal} from \\\"../../interfaces/IBentoBoxMinimal.sol\\\";\\nimport {IPool} from \\\"../../interfaces/IPool.sol\\\";\\nimport {ITridentCallee} from \\\"../../interfaces/ITridentCallee.sol\\\";\\nimport {IConstantProductPoolFactory} from \\\"../../interfaces/IConstantProductPoolFactory.sol\\\";\\nimport {IMasterDeployer} from \\\"../../interfaces/IMasterDeployer.sol\\\";\\n\\nimport {TridentMath} from \\\"../../libraries/TridentMath.sol\\\";\\n\\n/// @dev Custom Errors\\nerror ZeroAddress();\\nerror IdenticalAddress();\\nerror InvalidSwapFee();\\nerror InvalidAmounts();\\nerror InsufficientLiquidityMinted();\\nerror InvalidOutputToken();\\nerror InvalidInputToken();\\nerror PoolUninitialized();\\nerror InsufficientAmountIn();\\nerror Overflow();\\n\\n/// @notice Trident exchange pool template with constant product formula for swapping between an ERC-20 token pair.\\n/// @dev The reserves are stored as bento shares.\\n/// The curve is applied to shares as well. This pool does not care about the underlying amounts.\\ncontract ConstantProductPool is IPool, ERC20, ReentrancyGuard {\\n event Mint(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient);\\n event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed recipient);\\n event Sync(uint256 reserve0, uint256 reserve1);\\n\\n uint256 internal constant MINIMUM_LIQUIDITY = 1000;\\n\\n uint8 internal constant PRECISION = 112;\\n uint256 internal constant MAX_FEE = 10000; // @dev 100%.\\n uint256 public immutable swapFee;\\n uint256 internal immutable MAX_FEE_MINUS_SWAP_FEE;\\n\\n IBentoBoxMinimal public immutable bento;\\n IMasterDeployer public immutable masterDeployer;\\n address public immutable token0;\\n address public immutable token1;\\n\\n uint256 public barFee;\\n address public barFeeTo;\\n uint256 public price0CumulativeLast;\\n uint256 public price1CumulativeLast;\\n uint256 public kLast;\\n\\n uint112 internal reserve0;\\n uint112 internal reserve1;\\n uint32 internal blockTimestampLast;\\n\\n bytes32 public constant override poolIdentifier = \\\"Trident:ConstantProduct\\\";\\n\\n constructor() ERC20(\\\"Sushi Constant Product LP Token\\\", \\\"SCPLP\\\", 18) {\\n (bytes memory _deployData, IMasterDeployer _masterDeployer) = IConstantProductPoolFactory(msg.sender).getDeployData();\\n\\n (address _token0, address _token1, uint256 _swapFee, bool _twapSupport) = abi.decode(\\n _deployData,\\n (address, address, uint256, bool)\\n );\\n\\n // Factory ensures that the tokens are sorted.\\n if (_token0 == address(0)) revert ZeroAddress();\\n if (_token0 == _token1) revert IdenticalAddress();\\n if (_swapFee > MAX_FEE) revert InvalidSwapFee();\\n\\n token0 = _token0;\\n token1 = _token1;\\n swapFee = _swapFee;\\n // This is safe from underflow - `swapFee` cannot exceed `MAX_FEE` per previous check.\\n unchecked {\\n MAX_FEE_MINUS_SWAP_FEE = MAX_FEE - _swapFee;\\n }\\n barFee = _masterDeployer.barFee();\\n barFeeTo = _masterDeployer.barFeeTo();\\n bento = IBentoBoxMinimal(_masterDeployer.bento());\\n masterDeployer = _masterDeployer;\\n if (_twapSupport) blockTimestampLast = uint32(block.timestamp);\\n }\\n\\n /// @dev Mints LP tokens - should be called via the router after transferring `bento` tokens.\\n /// The router must ensure that sufficient LP tokens are minted by using the return value.\\n function mint(bytes calldata data) public override nonReentrant returns (uint256 liquidity) {\\n address recipient = abi.decode(data, (address));\\n (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n (uint256 balance0, uint256 balance1) = _balance();\\n\\n uint256 computed = TridentMath.sqrt(balance0 * balance1);\\n uint256 amount0 = balance0 - _reserve0;\\n uint256 amount1 = balance1 - _reserve1;\\n\\n (uint256 fee0, uint256 fee1) = _nonOptimalMintFee(amount0, amount1, _reserve0, _reserve1);\\n _reserve0 += uint112(fee0);\\n _reserve1 += uint112(fee1);\\n\\n (uint256 _totalSupply, uint256 k) = _mintFee(_reserve0, _reserve1);\\n\\n if (_totalSupply == 0) {\\n if (amount0 == 0 || amount1 == 0) revert InvalidAmounts();\\n liquidity = computed - MINIMUM_LIQUIDITY;\\n _mint(address(0), MINIMUM_LIQUIDITY);\\n } else {\\n uint256 kIncrease;\\n unchecked {\\n kIncrease = computed - k;\\n }\\n liquidity = (kIncrease * _totalSupply) / k;\\n }\\n if (liquidity == 0) revert InsufficientLiquidityMinted();\\n _mint(recipient, liquidity);\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n kLast = computed;\\n emit Mint(msg.sender, amount0, amount1, recipient);\\n }\\n\\n /// @dev Burns LP tokens sent to this contract. The router must ensure that the user gets sufficient output tokens.\\n function burn(bytes calldata data) public override nonReentrant returns (IPool.TokenAmount[] memory withdrawnAmounts) {\\n (address recipient, bool unwrapBento) = abi.decode(data, (address, bool));\\n (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n (uint256 balance0, uint256 balance1) = _balance();\\n uint256 liquidity = balanceOf[address(this)];\\n\\n (uint256 _totalSupply, ) = _mintFee(_reserve0, _reserve1);\\n\\n uint256 amount0 = (liquidity * balance0) / _totalSupply;\\n uint256 amount1 = (liquidity * balance1) / _totalSupply;\\n\\n _burn(address(this), liquidity);\\n _transfer(token0, amount0, recipient, unwrapBento);\\n _transfer(token1, amount1, recipient, unwrapBento);\\n // This is safe from underflow - amounts are lesser figures derived from balances.\\n unchecked {\\n balance0 -= amount0;\\n balance1 -= amount1;\\n }\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n kLast = TridentMath.sqrt(balance0 * balance1);\\n\\n withdrawnAmounts = new TokenAmount[](2);\\n withdrawnAmounts[0] = TokenAmount({token: address(token0), amount: amount0});\\n withdrawnAmounts[1] = TokenAmount({token: address(token1), amount: amount1});\\n emit Burn(msg.sender, amount0, amount1, recipient);\\n }\\n\\n /// @dev Burns LP tokens sent to this contract and swaps one of the output tokens for another\\n /// - i.e., the user gets a single token out by burning LP tokens.\\n function burnSingle(bytes calldata data) public override nonReentrant returns (uint256 amountOut) {\\n (address tokenOut, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool));\\n (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n uint256 liquidity = balanceOf[address(this)];\\n\\n (uint256 _totalSupply, ) = _mintFee(_reserve0, _reserve1);\\n\\n uint256 amount0 = (liquidity * _reserve0) / _totalSupply;\\n uint256 amount1 = (liquidity * _reserve1) / _totalSupply;\\n\\n kLast = TridentMath.sqrt((_reserve0 - amount0) * (_reserve1 - amount1));\\n\\n _burn(address(this), liquidity);\\n\\n // Swap one token for another\\n unchecked {\\n if (tokenOut == token1) {\\n // Swap `token0` for `token1`\\n // - calculate `amountOut` as if the user first withdrew balanced liquidity and then swapped `token0` for `token1`.\\n amount1 += _getAmountOut(amount0, _reserve0 - amount0, _reserve1 - amount1);\\n _transfer(token1, amount1, recipient, unwrapBento);\\n amountOut = amount1;\\n amount0 = 0;\\n } else {\\n // Swap `token1` for `token0`.\\n if (tokenOut != token0) revert InvalidOutputToken();\\n amount0 += _getAmountOut(amount1, _reserve1 - amount1, _reserve0 - amount0);\\n _transfer(token0, amount0, recipient, unwrapBento);\\n amountOut = amount0;\\n amount1 = 0;\\n }\\n }\\n\\n (uint256 balance0, uint256 balance1) = _balance();\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n\\n emit Burn(msg.sender, amount0, amount1, recipient);\\n }\\n\\n /// @dev Swaps one token for another. The router must prefund this contract and ensure there isn't too much slippage.\\n function swap(bytes calldata data) public override nonReentrant returns (uint256 amountOut) {\\n (address tokenIn, address recipient, bool unwrapBento) = abi.decode(data, (address, address, bool));\\n (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n if (_reserve0 == 0) revert PoolUninitialized();\\n (uint256 balance0, uint256 balance1) = _balance();\\n uint256 amountIn;\\n address tokenOut;\\n unchecked {\\n if (tokenIn == token0) {\\n tokenOut = token1;\\n amountIn = balance0 - _reserve0;\\n amountOut = _getAmountOut(amountIn, _reserve0, _reserve1);\\n balance1 -= amountOut;\\n } else {\\n if (tokenIn != token1) revert InvalidInputToken();\\n tokenOut = token0;\\n amountIn = balance1 - reserve1;\\n amountOut = _getAmountOut(amountIn, _reserve1, _reserve0);\\n balance0 -= amountOut;\\n }\\n }\\n _transfer(tokenOut, amountOut, recipient, unwrapBento);\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n emit Swap(recipient, tokenIn, tokenOut, amountIn, amountOut);\\n }\\n\\n /// @dev Swaps one token for another. The router must support swap callbacks and ensure there isn't too much slippage.\\n function flashSwap(bytes calldata data) public override nonReentrant returns (uint256 amountOut) {\\n (address tokenIn, address recipient, bool unwrapBento, uint256 amountIn, bytes memory context) = abi.decode(\\n data,\\n (address, address, bool, uint256, bytes)\\n );\\n (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) = _getReserves();\\n if (_reserve0 == 0) revert PoolUninitialized();\\n unchecked {\\n if (tokenIn == token0) {\\n amountOut = _getAmountOut(amountIn, _reserve0, _reserve1);\\n _transfer(token1, amountOut, recipient, unwrapBento);\\n ITridentCallee(msg.sender).tridentSwapCallback(context);\\n (uint256 balance0, uint256 balance1) = _balance();\\n if (balance0 - _reserve0 < amountIn) revert InsufficientAmountIn();\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n emit Swap(recipient, tokenIn, token1, amountIn, amountOut);\\n } else {\\n if (tokenIn != token1) revert InvalidInputToken();\\n amountOut = _getAmountOut(amountIn, _reserve1, _reserve0);\\n _transfer(token0, amountOut, recipient, unwrapBento);\\n ITridentCallee(msg.sender).tridentSwapCallback(context);\\n (uint256 balance0, uint256 balance1) = _balance();\\n if (balance1 - _reserve1 < amountIn) revert InsufficientAmountIn();\\n _update(balance0, balance1, _reserve0, _reserve1, _blockTimestampLast);\\n emit Swap(recipient, tokenIn, token0, amountIn, amountOut);\\n }\\n }\\n }\\n\\n /// @dev Updates `barFee` and `barFeeTo` for Trident protocol.\\n function updateBarParameters() public {\\n barFee = masterDeployer.barFee();\\n barFeeTo = masterDeployer.barFeeTo();\\n }\\n\\n function _getReserves()\\n internal\\n view\\n returns (\\n uint112 _reserve0,\\n uint112 _reserve1,\\n uint32 _blockTimestampLast\\n )\\n {\\n _reserve0 = reserve0;\\n _reserve1 = reserve1;\\n _blockTimestampLast = blockTimestampLast;\\n }\\n\\n function _balance() internal view returns (uint256 balance0, uint256 balance1) {\\n balance0 = bento.balanceOf(token0, address(this));\\n balance1 = bento.balanceOf(token1, address(this));\\n }\\n\\n function _update(\\n uint256 balance0,\\n uint256 balance1,\\n uint112 _reserve0,\\n uint112 _reserve1,\\n uint32 _blockTimestampLast\\n ) internal {\\n if (balance0 > type(uint112).max || balance1 > type(uint112).max) revert Overflow();\\n if (_blockTimestampLast == 0) {\\n // TWAP support is disabled for gas efficiency.\\n reserve0 = uint112(balance0);\\n reserve1 = uint112(balance1);\\n } else {\\n uint32 blockTimestamp = uint32(block.timestamp);\\n if (blockTimestamp != _blockTimestampLast && _reserve0 != 0 && _reserve1 != 0) {\\n unchecked {\\n uint32 timeElapsed = blockTimestamp - _blockTimestampLast;\\n