Address Contract Verified
Address
0x053A4EC128d6788dfE5b1f89dd6a6019E0532f2D
Balance
0 ETH
Nonce
1
Code Size
8654 bytes
Creator
0x2D0741C2...581d at tx 0x3aa8a4b6...3ec0ce
Indexed Transactions
0
Contract Bytecode
8654 bytes
0x6080806040526004361015610059575b50361561001a575f80fd5b60ff600754161561002757005b60405162461bcd60e51b815260206004820152600a602482015269141c9bda1a589a5d195960b21b6044820152606490fd5b5f3560e01c90816306fdde031461173357508063095ea7b31461168657806318160ddd14611669578063191a48451461161757806323b872dd1461150d578063249b7c19146114d357806328a678b1146113ee578063313ce567146113d35780634020b317146113995780634555a5aa146112865780634632f560146112185780634f5f21cf146111de57806361d027b31461119a57806363e1289b1461106b5780636a576112146110095780636b7cbf1114610fcf57806370a0823114610f97578063756c79db14610c3457806395d89b4114610b30578063a1af3e5e14610b04578063a7c6402c14610ad6578063a9059cbb14610a7a578063b753bfe914610a36578063bd977c75146109ea578063c154b2851461091f578063c841c4af1461054a578063cab64bcd14610506578063cc32d4da1461038f578063d0e30db014610324578063d5d0e9eb146102d6578063d7e66d141461029c578063dd62ed3e1461024c578063ed338ff1146102125763f75a854e146101db575f61000f565b3461020e5760206102066101f76101f136611898565b90611e27565b670de0b6b3a764000090611e3a565b604051908152f35b5f80fd5b3461020e575f36600319011261020e5760206040517f000000000000000000000000000000000000000000000000000000006955b8ff8152f35b3461020e57604036600319011261020e57610265611815565b61026d61182b565b6001600160a01b039182165f908152600160209081526040808320949093168252928352819020549051908152f35b3461020e575f36600319011261020e5760206040517f00000000000000000000000000000000000000000000000000000000000001f48152f35b3461020e575f36600319011261020e576001600160a01b037f00000000000000000000000023038526217fe168e46ac887cf9ebf80a2e93589165f9081526020818152604090912054610206565b5f36600319011261020e57610363337f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03161461195a565b7fa1ab46d0e38f33a7b1f03853088a305927deb55c906370ff5d6d2bc732f150956020604051348152a1005b3461020e57602036600319011261020e576004356103ce7f000000000000000000000000000000000000000000000000000000006955b8ff42116118e4565b6103f97f000000000000000000000000000000000000000000000000000000006b36ec7f4210611a38565b610401611edc565b61040c811515611e58565b335f5260066020528060405f2054106104b05761044c6101f77f000000000000000000000000000000000000000000000000000016bcc41e900083611e27565b809161047782159161045e8315611e9b565b335f52600660205260405f2081815403905530336120ee565b5f906104a7575b5f80809381933390f11561049c576020906001600555604051908152f35b6040513d5f823e3d90fd5b506108fc61047e565b60405162461bcd60e51b815260206004820152602860248201527f496e73756666696369656e742070726573616c65206275796261636b20656c69604482015267676962696c69747960c01b6064820152608490fd5b3461020e575f36600319011261020e576040517f00000000000000000000000023038526217fe168e46ac887cf9ebf80a2e935896001600160a01b03168152602090f35b3461020e57608036600319011261020e57610563611815565b60243560443567ffffffffffffffff811161020e57610586903690600401611867565b606492919235936105b97f000000000000000000000000000000000000000000000000000000006955b8ff421115611921565b6105e47f00000000000000000000000000000000000000000000000000000000692e2bff42116119f8565b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b039190911693906020816064815f895af1801561049c57610633915f91610900575b50611ad0565b60405163095ea7b360e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d6004820152602481018490526020816044815f895af1801561049c57610682915f916108e1575b50611b1c565b600282018083116108085761069690611b91565b91846106a184611bc3565b525f5b8181106108a55750506040516315ab88c960e31b8152939050602084600481737a250d5630b4cf539739df2c5dacb4c659f2488d5afa93841561049c575f94610874575b5081515f198101949085116108085761070461073f9584611be4565b9060018060a01b031690525f4793600160ff196007541617600755604051809681926318cbafe560e01b83524290878b309260048701611ca3565b038183737a250d5630b4cf539739df2c5dacb4c659f2488d5af193841561049c575f9461084b575b5060205f9160ff196007541660075560446040518094819363095ea7b360e01b8352737a250d5630b4cf539739df2c5dacb4c659f2488d60048401528160248401525af1801561049c576107c2915f9161081c575b50611d0b565b515f19810192908311610808576020936107fb6107f5936107e96102069661080295611be4565b51948593841015611d6f565b47611c1c565b1015611dcb565b33611efc565b634e487b7160e01b5f52601160045260245ffd5b61083e915060203d602011610844575b61083681836118ae565b810190611ab8565b866107bc565b503d61082c565b5f91945061086c6020913d8085833e61086481836118ae565b810190611c29565b949150610767565b61089791945060203d60201161089e575b61088f81836118ae565b810190611996565b92856106e8565b503d610885565b6108b86108b3828486611bf8565b611c08565b906001810191828211610808576108d160019387611be4565b90838060a01b03169052016106a4565b6108fa915060203d6020116108445761083681836118ae565b8761067c565b610919915060203d6020116108445761083681836118ae565b8761062d565b3461020e57602036600319011261020e577f29d244d11de399832a378f3590408ea4c6aa2b1af6230d5fbc74a35d83df1143602060043561098a337f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03161461195a565b6109b67f000000000000000000000000000000000000000000000000000000006955b8ff421115611921565b6109e181307f00000000000000000000000081ddebe780e4b27395e7bbc55017fc2fd0d2a9966120ee565b604051908152a1005b602036600319011261020e576020610206610a03611815565b610a2f7f00000000000000000000000000000000000000000000000000000000692e2bff421115611a7c565b3433611f58565b3461020e575f36600319011261020e576040517f00000000000000000000000081ddebe780e4b27395e7bbc55017fc2fd0d2a9966001600160a01b03168152602090f35b3461020e57604036600319011261020e57610acb610a96611815565b610ac17f000000000000000000000000000000000000000000000000000000006955b8ff42116118e4565b60243590336120ee565b602060405160018152f35b3461020e575f36600319011261020e576020604051737a250d5630b4cf539739df2c5dacb4c659f2488d8152f35b3461020e576020610206610b2b610b1a36611898565b9190670de0b6b3a764000090611e27565b611e3a565b3461020e575f36600319011261020e576040515f6004548060011c90600181168015610c2a575b602083108114610c1657828552908115610bf25750600114610b94575b610b9083610b84818503826118ae565b604051918291826117eb565b0390f35b91905060045f527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b915f905b808210610bd857509091508101602001610b84610b74565b919260018160209254838588010152019101909291610bc0565b60ff191660208086019190915291151560051b84019091019150610b849050610b74565b634e487b7160e01b5f52602260045260245ffd5b91607f1691610b57565b3461020e5760a036600319011261020e57610c4d611815565b60243560443567ffffffffffffffff811161020e57610c70903690600401611867565b606435939192608435929091906001600160a01b038416840361020e57610cb97f00000000000000000000000000000000000000000000000000000000692e2bff421115611a7c565b6040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b039190911694906020816064815f8a5af1801561049c57610d07915f91610f785750611ad0565b60405163095ea7b360e01b8152737a250d5630b4cf539739df2c5dacb4c659f2488d6004820152602481018490526020816044815f8a5af1801561049c57610d55915f91610f595750611b1c565b6002820180831161080857610d6990611b91565b9185610d7484611bc3565b525f5b818110610f225750506040516315ab88c960e31b8152949050602085600481737a250d5630b4cf539739df2c5dacb4c659f2488d5afa94851561049c575f95610f01575b5081515f1981019590861161080857610dd7610e129684611be4565b9060018060a01b031690525f4793600160ff196007541617600755604051809781926318cbafe560e01b83524290878c309260048701611ca3565b038183737a250d5630b4cf539739df2c5dacb4c659f2488d5af194851561049c575f95610ee0575b5060205f9160ff196007541660075560446040518094819363095ea7b360e01b8352737a250d5630b4cf539739df2c5dacb4c659f2488d60048401528160248401525af1801561049c57610e94915f91610ec15750611d0b565b515f19810193908411610808576020946107fb6107f5936107e961020697610ebb95611be4565b33611f58565b610eda915060203d6020116108445761083681836118ae565b876107bc565b5f919550610ef96020913d8085833e61086481836118ae565b959150610e3a565b610f1b91955060203d60201161089e5761088f81836118ae565b9386610dbb565b610f306108b3828486611bf8565b90600181019182821161080857610f4960019387611be4565b90838060a01b0316905201610d77565b610f72915060203d6020116108445761083681836118ae565b8861067c565b610f91915060203d6020116108445761083681836118ae565b8861062d565b3461020e57602036600319011261020e576020610206610fb5611815565b6001600160a01b03165f9081526020819052604090205490565b3461020e575f36600319011261020e5760206040517f00000000000000000000000000000000000000000000000000002d79883d20008152f35b3461020e57602036600319011261020e57611022611815565b61104d7f000000000000000000000000000000000000000000000000000000006b36ec7f4210611a38565b60018060a01b03165f526006602052602060405f2054604051908152f35b3461020e575f36600319011261020e576110af337f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03161461195a565b6110da7f000000000000000000000000000000000000000000000000000000006955b8ff42116118e4565b305f525f60205260405f2054301561118757305f525f60205260405f205481811061116e57817fea2cd71ff9f81e81845e4657ef26f3929886b98613e064faa2dc3105cbb9a7ad92602092305f525f84520360405f205580600254036002555f6040518281527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef843092a3604051908152a1005b63391434e360e21b5f523060045260245260445260645ffd5b634b637e8f60e11b5f525f60045260245ffd5b3461020e575f36600319011261020e576040517f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03168152602090f35b3461020e575f36600319011261020e5760206040517f000000000000000000000000000000000000000000000000000016bcc41e90008152f35b5f36600319011261020e5761124f7f000000000000000000000000000000000000000000000000000000006955b8ff421115611921565b61127a7f00000000000000000000000000000000000000000000000000000000692e2bff42116119f8565b60206102063433611efc565b3461020e5761129436611841565b906112c9337f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03161461195a565b6112d1611edc565b6040516315daf18f60e11b8152906001600160a01b0316602082600481845afa91821561049c57602092611317915f9161137c575b506001600160a01b031630146119b5565b60046040518094819363023197ab60e51b83525af1801561049c575f90611349575b6020906001600555604051908152f35b506020813d602011611374575b81611363602093836118ae565b8101031261020e5760209051611339565b3d9150611356565b6113939150843d861161089e5761088f81836118ae565b85611306565b3461020e575f36600319011261020e5760206040517f000000000000000000000000000000000000000000000000000000006b36ec7f8152f35b3461020e575f36600319011261020e57602060405160128152f35b3461020e576113fc36611841565b90611431337f000000000000000000000000d0b1d8125de0f8a9f3c0f60b4d6197e6adc1f2b66001600160a01b03161461195a565b611439611edc565b6040516315daf18f60e11b8152906001600160a01b0316602082600481845afa801561049c575f9361148160249260209587916114b657506001600160a01b031630146119b5565b604051948593849263f417fbed60e01b845260048401525af1801561049c575f90611349576020906001600555604051908152f35b6114cd9150863d881161089e5761088f81836118ae565b87611306565b3461020e575f36600319011261020e5760206040517f00000000000000000000000000000000000000000000000000000000692e2bff8152f35b3461020e57606036600319011261020e57611526611815565b61152e61182b565b6044359061155d7f000000000000000000000000000000000000000000000000000000006955b8ff42116118e4565b6001600160a01b0383165f8181526001602090815260408083203384529091529020549093905f198110611597575b50610acb93506120ee565b8381106115fc5784156115e95733156115d657610acb945f52600160205260405f2060018060a01b0333165f526020528360405f20910390558461158c565b634a1406b160e11b5f525f60045260245ffd5b63e602df0560e01b5f525f60045260245ffd5b8390637dc7a0d960e11b5f523360045260245260445260645ffd5b3461020e575f36600319011261020e576116537f000000000000000000000000000000000000000000000000000000006955b8ff421115611921565b305f525f602052602060405f2054604051908152f35b3461020e575f36600319011261020e576020600254604051908152f35b3461020e57604036600319011261020e5761169f611815565b602435906116ce7f000000000000000000000000000000000000000000000000000000006955b8ff42116118e4565b33156115e9576001600160a01b03169081156115d657335f52600160205260405f20825f526020528060405f20556040519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560203392a3602060405160018152f35b3461020e575f36600319011261020e575f6003548060011c906001811680156117e1575b602083108114610c1657828552908115610bf2575060011461178357610b9083610b84818503826118ae565b91905060035f527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b915f905b8082106117c757509091508101602001610b84610b74565b9192600181602092548385880101520191019092916117af565b91607f1691611757565b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361020e57565b602435906001600160a01b038216820361020e57565b604090600319011261020e576004356001600160a01b038116810361020e579060243590565b9181601f8401121561020e5782359167ffffffffffffffff831161020e576020808501948460051b01011161020e57565b604090600319011261020e576004359060243590565b90601f8019910116810190811067ffffffffffffffff8211176118d057604052565b634e487b7160e01b5f52604160045260245ffd5b156118eb57565b60405162461bcd60e51b815260206004820152600e60248201526d14d85b19481b9bdd08195b99195960921b6044820152606490fd5b1561192857565b60405162461bcd60e51b815260206004820152600a60248201526914d85b1948195b99195960b21b6044820152606490fd5b1561196157565b60405162461bcd60e51b815260206004820152600d60248201526c1058d8d95cdcc819195b9a5959609a1b6044820152606490fd5b9081602091031261020e57516001600160a01b038116810361020e5790565b156119bc57565b60405162461bcd60e51b815260206004820152601460248201527324b73b30b634b210313934b233b2903a37b5b2b760611b6044820152606490fd5b156119ff57565b60405162461bcd60e51b8152602060048201526011602482015270141c995cd85b19481b9bdd08195b991959607a1b6044820152606490fd5b15611a3f57565b60405162461bcd60e51b8152602060048201526015602482015274141c995cd85b1948189d5e589858dac8195b991959605a1b6044820152606490fd5b15611a8357565b60405162461bcd60e51b815260206004820152600d60248201526c141c995cd85b1948195b991959609a1b6044820152606490fd5b9081602091031261020e5751801515810361020e5790565b15611ad757565b60405162461bcd60e51b815260206004820152601f60248201527f4661696c656420746f207472616e7366657220696e70757420746f6b656e73006044820152606490fd5b15611b2357565b60405162461bcd60e51b815260206004820152602860248201527f4661696c656420746f20617070726f766520696e70757420746f6b656e73207460448201526737903937baba32b960c11b6064820152608490fd5b67ffffffffffffffff81116118d05760051b60200190565b90611b9b82611b79565b611ba860405191826118ae565b8281528092611bb9601f1991611b79565b0190602036910137565b805115611bd05760200190565b634e487b7160e01b5f52603260045260245ffd5b8051821015611bd05760209160051b010190565b9190811015611bd05760051b0190565b356001600160a01b038116810361020e5790565b9190820391821161080857565b60208183031261020e5780519067ffffffffffffffff821161020e57019080601f8301121561020e578151611c5d81611b79565b92611c6b60405194856118ae565b81845260208085019260051b82010192831161020e57602001905b828210611c935750505090565b8151815260209182019101611c86565b92919594939560a08401918452602084015260a060408401528151809152602060c084019201905f5b818110611cec575050506001600160a01b03909416606082015260800152565b82516001600160a01b0316845260209384019390920191600101611ccc565b15611d1257565b60405162461bcd60e51b815260206004820152602f60248201527f4661696c656420746f20726573657420696e70757420746f6b656e732061707060448201526e3937bb30b6103a37903937baba32b960891b6064820152608490fd5b15611d7657565b60405162461bcd60e51b815260206004820152602760248201527f53776170206f75747075742045544820616d6f756e742069732062656c6f77206044820152666d696e696d756d60c81b6064820152608490fd5b15611dd257565b60405162461bcd60e51b815260206004820152602760248201527f53776170206f75747075742045544820616d6f756e7420776173206e6f7420726044820152661958d95a5d995960ca1b6064820152608490fd5b8181029291811591840414171561080857565b8115611e44570490565b634e487b7160e01b5f52601260045260245ffd5b15611e5f57565b60405162461bcd60e51b8152602060048201526014602482015273546f6b656e20616d6f756e74206973207a65726f60601b6044820152606490fd5b15611ea257565b60405162461bcd60e51b815260206004820152601260248201527145544820616d6f756e74206973207a65726f60701b6044820152606490fd5b600260055414611eed576002600555565b633ee5aeb560e01b5f5260045ffd5b90611f42611f5591611f0f811515611e9b565b610b2b670de0b6b3a76400007f00000000000000000000000000000000000000000000000000002d79883d200092611e27565b8092611f4f821515611e58565b306120ee565b90565b9190611f65811515611e9b565b6001600160a01b0383811693908316918285146120b757611fb390610b2b670de0b6b3a76400007f000000000000000000000000000000000000000000000000000016bcc41e900092611e27565b93611fbf851515611e58565b5f52600660205260405f2080549185830180931161080857611fe492869255306120ee565b7f00000000000000000000000023038526217fe168e46ac887cf9ebf80a2e935899160018060a01b0383165f525f60205260405f20549115158061208e575b80612085575b612034575b50505090565b612075926127106120657f00000000000000000000000000000000000000000000000000000000000001f487611e27565b049280841161207d575b506120ee565b5f808061202e565b92505f61206f565b50811515612029565b507f00000000000000000000000000000000000000000000000000000000000001f41515612023565b60405162461bcd60e51b815260206004820152600f60248201526e24b73b30b634b2103932b332b932b960891b6044820152606490fd5b6001600160a01b0316908115611187576001600160a01b031691821561218557815f525f60205260405f205481811061216c57817fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92602092855f525f84520360405f2055845f525f825260405f20818154019055604051908152a3565b8263391434e360e21b5f5260045260245260445260645ffd5b63ec442f0560e01b5f525f60045260245ffdfea26469706673582212201d6f9d5b1934ef4e324749f0251aa764ea08cfd39fe53199d0898d30647eb8d464736f6c634300081c0033
Verified Source Code Full Match
Compiler: v0.8.28+commit.7893614a
EVM: cancun
Optimization: Yes (200 runs)
draft-IERC6093.sol 161 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (interfaces/draft-IERC6093.sol)
pragma solidity >=0.8.4;
/**
* @dev Standard ERC-20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC-721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in ERC-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC-1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC-1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
ERC20.sol 305 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC-20
* applications.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* Both values are immutable: they can only be set once during construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/// @inheritdoc IERC20
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/// @inheritdoc IERC20
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/// @inheritdoc IERC20
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Skips emitting an {Approval} event indicating an allowance update. This is not
* required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve].
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner`'s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
*
* ```solidity
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner`'s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance < type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
IERC20.sol 79 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/IERC20.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
IERC20Metadata.sol 26 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity >=0.6.2;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
ReentrancyGuard.sol 87 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)
pragma solidity ^0.8.20;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
* consider using {ReentrancyGuardTransient} instead.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
uint256 private _status;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() {
_status = NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_status == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_status = ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == ENTERED;
}
}
IUniswapV2Router01.sol 95 lines
pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
IUniswapV2Router02.sol 44 lines
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
MockUnigate.sol 45 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "./Unigate.sol";
contract MockUnigateToken is UnigateToken {
IUniswapV2Router02 private immutable _uniswapV2Router02;
constructor(
address treasury_,
uint256 treasuryAllocationToken_,
address liquidityReserve_,
uint256 liquidityReserveAllocationToken_,
address rewardReserve_,
uint256 rewardReserveAllocationToken_,
uint256 saleEndTime_,
uint256 salePriceETH_,
uint256 presaleEndTime_,
uint256 presalePriceETH_,
uint256 presaleReferralRewardFactor_,
uint256 presaleBuybackGuaranteeEndTime_,
IUniswapV2Router02 uniswapV2Router02_
)
UnigateToken(
treasury_,
treasuryAllocationToken_,
liquidityReserve_,
liquidityReserveAllocationToken_,
rewardReserve_,
rewardReserveAllocationToken_,
saleEndTime_,
salePriceETH_,
presaleEndTime_,
presalePriceETH_,
presaleReferralRewardFactor_,
presaleBuybackGuaranteeEndTime_
)
{
_uniswapV2Router02 = uniswapV2Router02_;
}
function uniswapV2Router02() public view override returns (IUniswapV2Router02) {
return _uniswapV2Router02;
}
}
Unigate.sol 817 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
/**
* @title Unigate Bridge Token
* @author Unigate
* @notice Unigate bridge token base contract.
*/
abstract contract UnigateBridgeToken is ERC20 {
/**
* @notice Master token contract address.
*/
address public immutable masterToken;
/**
* @notice Initializes token parameters.
*
* @param name_ Token name.
* @param symbol_ Token symbol.
* @param masterToken_ Master token contract address.
*/
constructor(
string memory name_,
string memory symbol_,
address masterToken_
) ERC20(name_, symbol_) {
require(masterToken_ != address(0), "Master token contract address is zero");
masterToken = masterToken_;
}
/**
* @notice Checks that the caller (`_msgSender()`) is master token (`masterToken`).
*/
modifier onlyMaster() {
require(_msgSender() == masterToken, "Access denied");
_;
}
/**
* @notice Buys bridge tokens for ETH and transfers them to the caller (`_msgSender()`).
*
* ONLY avaiable to master token caller (`masterToken`).
*
* @return Token amount (in base units) transferred.
*/
function buyTokensForETH() external payable onlyMaster returns (uint256) {
// Calculate token amount
uint256 amountToken = (msg.value * (10 ** decimals())) / _priceETH();
// Transfer tokens from token reserve (token balance if `this`) to caller
_transfer(address(this), _msgSender(), amountToken);
return amountToken;
}
/**
* @notice Sells bridge tokens for ETH and transfers ETH to the caller (`_msgSender()`).
*
* ONLY avaiable to master token caller (`masterToken`).
*
* @param amountToken Token amount (in base units) to sell.
*
* @return ETH amount (in wei) transferred.
*/
function sellTokensForETH(uint256 amountToken) external onlyMaster returns (uint256) {
// Calculate ETH amount
uint256 amountETH = (amountToken * _priceETH()) / (10 ** decimals());
// Transfer tokens from caller to token reserve (token balance if `this`)
_transfer(_msgSender(), address(this), amountToken);
// Transfer ETH to caller
payable(_msgSender()).transfer(amountETH);
return amountETH;
}
/**
* @notice Gets token price.
*
* @return ETH amount (in wei) for 1 token.
*/
function _priceETH() internal virtual returns (uint256);
}
/**
* @title Unigate Token
* @author Unigate
* @notice Unigate token contract.
*/
contract UnigateToken is ERC20, ReentrancyGuard {
/**
* @notice Treasury address.
*/
address public immutable treasury;
/**
* @notice Liquidity reserve address.
*/
address public immutable liquidityReserve;
/**
* @notice Reward reserve address.
*/
address public immutable rewardReserve;
/**
* @notice Sale end time.
*/
uint256 public immutable saleEndTime;
/**
* @notice Sale price in ETH amount (in wei) for 1 token.
*/
uint256 public immutable salePriceETH;
/**
* @notice Presale end time.
*/
uint256 public immutable presaleEndTime;
/**
* @notice Presale price in ETH amount (in wei) for 1 token.
*/
uint256 public immutable presalePriceETH;
/**
* @notice Presale referral reward factor in percent (with two decimals).
*
* A value of 10000 represents 100.00%.
*/
uint256 public immutable presaleReferralRewardFactorPercent;
/**
* @notice Presale buyback end time.
*/
uint256 public immutable presaleBuybackEndTime;
/**
* @notice Token amount (in base units) eligible for presale buyback per account.
*/
mapping(address => uint256) private _presaleBuybackEligibileToken;
/**
* @notice Initializes token parameters.
*
* @param treasury_ Treasury address.
* @param treasuryAllocationToken_ Treasury initial allocation token amount (in base units).
* @param liquidityReserve_ Liquidity reserve address.
* @param liquidityReserveAllocationToken_ Liquidity reserve initial allocation token amount (in base units).
* @param rewardReserve_ Reward reserve address.
* @param rewardReserveAllocationToken_ Reward reserve initial allocation token amount (in base units).
* @param saleEndTime_ Sale end time.
* @param salePriceETH_ Sale price in ETH amount (in wei) per 1 token.
* @param presaleEndTime_ Presale end time.
* @param presalePriceETH_ Presale price in ETH amount (in wei) per 1 token.
* @param presaleReferralRewardFactorPercent_ Presale referral reward factor in percent (with two decimals).
* @param presaleBuybackEndTime_ Presale buyback end time.
*/
constructor(
address treasury_,
uint256 treasuryAllocationToken_,
address liquidityReserve_,
uint256 liquidityReserveAllocationToken_,
address rewardReserve_,
uint256 rewardReserveAllocationToken_,
uint256 saleEndTime_,
uint256 salePriceETH_,
uint256 presaleEndTime_,
uint256 presalePriceETH_,
uint256 presaleReferralRewardFactorPercent_,
uint256 presaleBuybackEndTime_
) ERC20("UnigateToken", "UGTT") {
// Set up treasury
require(treasury_ != address(0), "Treasury address is zero");
treasury = treasury_;
_mint(treasury_, treasuryAllocationToken_);
// Set up liquidity reserve
require(liquidityReserve_ != address(0), "Liquidity reserve address is zero");
require(liquidityReserveAllocationToken_ > 0, "Liquidity reserve allocation is zero");
liquidityReserve = liquidityReserve_;
_mint(liquidityReserve_, liquidityReserveAllocationToken_);
// Set up reward reserve
require(rewardReserve_ != address(0), "Reward reserve address is zero");
rewardReserve = rewardReserve_;
_mint(rewardReserve_, rewardReserveAllocationToken_);
// Set up sale
require(saleEndTime_ > block.timestamp, "Sale end time already passed");
require(salePriceETH_ > 0, "Sale price is zero");
saleEndTime = saleEndTime_;
salePriceETH = salePriceETH_;
// Set up presale
require(presaleEndTime_ > block.timestamp, "Presale end time already passed");
require(presaleEndTime_ < saleEndTime, "Presale end time later than sale end time");
require(presalePriceETH_ > 0, "Presale price is zero");
require(
presaleBuybackEndTime_ > presaleEndTime_,
"Buyback end time earlier than presale end time"
);
presaleEndTime = presaleEndTime_;
presalePriceETH = presalePriceETH_;
presaleReferralRewardFactorPercent = presaleReferralRewardFactorPercent_;
presaleBuybackEndTime = presaleBuybackEndTime_;
}
/**
* @notice Calculates token amount for ETH amount.
*
* @param amountETH ETH amount (in wei).
* @param rateETH Conversion rate in ETH amount (in wei) per 1 token.
*
* @return Token amount (in base units).
*/
function calcTokenFromETH(uint256 amountETH, uint256 rateETH) public view returns (uint256) {
return (amountETH * (10 ** decimals())) / rateETH;
}
/**
* @notice Calculates ETH amount for token amount.
*
* @param amountToken Token amount (in base units).
* @param rateETH Conversion rate in ETH amount (in wei) per 1 token.
*
* @return ETH amount (in wei).
*/
function calcETHFromToken(uint256 amountToken, uint256 rateETH) public view returns (uint256) {
return (amountToken * rateETH) / (10 ** decimals());
}
/**
* @notice Checks that the caller (`_msgSender()`) is treasury (`treasury`).
*/
modifier onlyTreasury() {
require(_msgSender() == treasury, "Access denied");
_;
}
/**
* @notice Checks that sale is running.
*/
modifier onlyDuringSale() {
require(block.timestamp <= saleEndTime, "Sale ended");
_;
}
/**
* @notice Checks that sale has ended.
*/
modifier onlyAfterSale() {
require(block.timestamp > saleEndTime, "Sale not ended");
_;
}
/**
* @notice Checks that presale is running.
*/
modifier onlyDuringPresale() {
require(block.timestamp <= presaleEndTime, "Presale ended");
_;
}
/**
* @notice Checks that presale has ended.
*/
modifier onlyAfterPresale() {
require(block.timestamp > presaleEndTime, "Presale not ended");
_;
}
/**
* @notice Checks that presale buyback is running.
*/
modifier onlyDuringPresaleBuyback() {
require(block.timestamp < presaleBuybackEndTime, "Presale buyback ended");
_;
}
/**
* @inheritdoc ERC20
*
* @notice ONLY available AFTER sale ends (`saleEndTime`).
*/
function transfer(address to, uint256 value) public override onlyAfterSale returns (bool) {
return super.transfer(to, value);
}
/**
* @inheritdoc ERC20
*
* @notice ONLY available AFTER sale ends (`saleEndTime`).
*/
function approve(address spender, uint256 value) public override onlyAfterSale returns (bool) {
return super.approve(spender, value);
}
/**
* @inheritdoc ERC20
*
* @notice ONLY available AFTER sale ends (`saleEndTime`).
*/
function transferFrom(
address from,
address to,
uint256 value
) public override onlyAfterSale returns (bool) {
return super.transferFrom(from, to, value);
}
/**
* @notice Gets balance of reward reserve (`rewardReserve`).
*
* @return Token amount (in base units).
*/
function balanceOfRewardReserve() external view returns (uint256) {
return balanceOf(rewardReserve);
}
/**
* @notice Gets balance of sale reserve (`this`).
*
* ONLY available BEFORE sale ends (`saleEndTime`).
*
* @return Token amount (in base units).
*/
function balanceOfSaleReserve() external view onlyDuringSale returns (uint256) {
return balanceOf(address(this));
}
/**
* @notice Buys tokens for ETH at sale price (`salePriceETH`) and
* transfers them to the caller (`_msgSender()`).
*
* ONLY available AFTER presale ends (`presaleEndTime`) and
* BEFORE sale ends (`saleEndTime`).
*
* @return Token amount (in base units) transferred.
*/
function buyTokensForETH() external payable onlyDuringSale onlyAfterPresale returns (uint256) {
// Credit tokens - ETH is received directly by contract
return _commitSale(_msgSender(), msg.value);
}
/**
* @notice Buys tokens for input tokens at sale price (`salePriceETH`),
* swapping input tokens for ETH via Uniswap (`uniswapV2Router02`) and
* transfers them to the caller (`_msgSender()`).
*
* ONLY available AFTER presale ends (`presaleEndTime`) and
* BEFORE sale ends (`saleEndTime`).
*
* @param inputToken Input token contract address.
* @param amountInputToken Input token amount (in base units).
* @param swapPath Intermediate token contract addresses, if any.
* @param minAmountETH Minimum output ETH amount (in wei).
*
* @return Token amount (in base units) transferred.
*/
function buyTokensForTokens(
IERC20 inputToken,
uint256 amountInputToken,
address[] calldata swapPath,
uint256 minAmountETH
) external onlyDuringSale onlyAfterPresale returns (uint256) {
// Collect input tokens from caller
require(
inputToken.transferFrom(_msgSender(), address(this), amountInputToken),
"Failed to transfer input tokens"
);
IUniswapV2Router02 router = uniswapV2Router02();
// Set allowance on input tokens for router
require(
inputToken.approve(address(router), amountInputToken),
"Failed to approve input tokens to router"
);
// Build full swap path, including input and output tokens
address[] memory fullSwapPath = new address[](swapPath.length + 2);
fullSwapPath[0] = address(inputToken);
for (uint256 i = 0; i < swapPath.length; i++) {
fullSwapPath[i + 1] = swapPath[i];
}
fullSwapPath[fullSwapPath.length - 1] = router.WETH();
// Store initial balance
uint256 initialBalanceETH = address(this).balance;
// Enable direct receive
_expectReceive = true;
// Swap input tokens for ETH
uint256[] memory amounts = router.swapExactTokensForETH(
amountInputToken,
minAmountETH,
fullSwapPath,
address(this),
block.timestamp
);
// Disable direct receive
_expectReceive = false;
// Reset allowance on input tokens for router
require(
inputToken.approve(address(router), 0),
"Failed to reset input tokens approval to router"
);
// Determine output ETH amount
uint256 amountETH = amounts[fullSwapPath.length - 1];
require(amountETH >= minAmountETH, "Swap output ETH amount is below minimum");
// Check balance after swap
require(
(address(this).balance - initialBalanceETH) >= amountETH,
"Swap output ETH amount was not received"
);
// Credit tokens to caller
return _commitSale(_msgSender(), amountETH);
}
/**
* @notice Buys tokens for ETH at presale price (`presalePriceETH`) and
* transfers them to the caller (`_msgSender()`).
*
* Credits presale buyback eligibility (`presaleBuybackEligibilityOf`) to
* caller for purchased token amount.
*
* If referrer (`referrer`) is non-zero, transfers referral reward,
* according to referral reward factor (`presaleReferralRewardFactorPercent`)
* and the purchased token amount, from reward reserve (`rewardReserve`)
* to referrer. Referrer MAY NOT be the same as caller.
*
* ONLY available BEFORE presale ends (`presaleEndTime`).
*
* @param referer Referer account address or zero address.
*
* @return Token amount (in base units) transferred.
*/
function presaleBuyTokensForETH(
address referer
) external payable onlyDuringPresale returns (uint256) {
// Credit tokens - ETH is received directly by contract
return _commitPresale(_msgSender(), msg.value, referer);
}
/**
* @notice Buys tokens for input tokens at presale price (`presalePriceETH`),
* swapping input tokens for ETH via Uniswap (`UniswapV2Router02`) and
* transfers them to the caller (`_msgSender()`).
*
* Credits presale buyback eligibility (`presaleBuybackEligibilityOf`) to
* caller for purchased tokens.
*
* If referrer (`referrer`) is non-zero, transfers referral reward,
* according to referral reward factor (`presaleReferralRewardFactorPercent`)
* and the purchased token amount, from reward reserve (`rewardReserve`)
* to referrer. Referrer MAY NOT be the same as caller.
*
* ONLY available BEFORE presale ends (`presaleEndTime`).
*
* @param inputToken Input token contract address.
* @param amountInputToken Input token amount (in base units).
* @param swapPath Intermediate token contract addresses, if any.
* @param minAmountETH Minimum ETH amount (in wei).
* @param referer Referer account address or zero address.
*
* @return Token amount (in base units) transferred.
*/
function presaleBuyTokensForTokens(
IERC20 inputToken,
uint256 amountInputToken,
address[] calldata swapPath,
uint256 minAmountETH,
address referer
) external onlyDuringPresale returns (uint256) {
// Collect input tokens from caller
require(
inputToken.transferFrom(_msgSender(), address(this), amountInputToken),
"Failed to transfer input tokens"
);
IUniswapV2Router02 router = uniswapV2Router02();
// Set allowance on input tokens for router
require(
inputToken.approve(address(router), amountInputToken),
"Failed to approve input tokens to router"
);
// Build full swap path, including input and output tokens
address[] memory fullSwapPath = new address[](swapPath.length + 2);
fullSwapPath[0] = address(inputToken);
for (uint256 i = 0; i < swapPath.length; i++) {
fullSwapPath[i + 1] = swapPath[i];
}
fullSwapPath[fullSwapPath.length - 1] = router.WETH();
// Store initial balance
uint256 initialBalanceETH = address(this).balance;
// Enable direct receive
_expectReceive = true;
// Swap input tokens for ETH
uint256[] memory amounts = router.swapExactTokensForETH(
amountInputToken,
minAmountETH,
fullSwapPath,
address(this),
block.timestamp
);
// Disable direct receive
_expectReceive = false;
// Reset allowance on input tokens for router
require(
inputToken.approve(address(router), 0),
"Failed to reset input tokens approval to router"
);
// Determine output ETH amount
uint256 amountETH = amounts[fullSwapPath.length - 1];
require(amountETH >= minAmountETH, "Swap output ETH amount is below minimum");
// Check balance after swap
require(
(address(this).balance - initialBalanceETH) >= amountETH,
"Swap output ETH amount was not received"
);
// Credit tokens to caller
return _commitPresale(_msgSender(), amountETH, referer);
}
/**
* @notice Gets presale buyback eligibility for the specified account.
*
* ONLY available BEFORE presale buyback ends (`presaleBuybackEndTime`).
*
* @param account Account address.
*
* @return Token amount (in base units) eligible for presale buyback.
*/
function presaleBuybackEligibilityOf(
address account
) external view onlyDuringPresaleBuyback returns (uint256) {
return _presaleBuybackEligibileToken[account];
}
/**
* @notice Sells tokens back for ETH at presale price (`presalePriceETH`)
* and transfers ETH amount to the caller (`_msgSender()`).
*
* Debits caller presale buyback eligibility (`presaleBuybackEligibilityOf`).
* FAILS if insufficient.
*
* ONLY available AFTER sale ends (`saleEndTime`) and
* BEFORE presale buyback ends (`presaleBuybackEndTime`).
*
* @param amountToken Token amount (in base units) to sell.
*
* @return ETH amount (in wei) transferred.
*/
function sellPresaleBuybackTokensForETH(
uint256 amountToken
) external onlyAfterSale onlyDuringPresaleBuyback nonReentrant returns (uint256) {
require(amountToken > 0, "Token amount is zero");
require(
_presaleBuybackEligibileToken[_msgSender()] >= amountToken,
"Insufficient presale buyback eligibility"
);
// Calculate ETH amount
uint256 amountETH = calcETHFromToken(amountToken, presalePriceETH);
require(amountETH > 0, "ETH amount is zero");
// Presale buyback eligibility already verified via `require`
unchecked {
// Debit presale buyback eligibility from caller
_presaleBuybackEligibileToken[_msgSender()] -= amountToken;
}
// Transfer tokens from caller to sale reserve (token balance of `this`)
_transfer(_msgSender(), address(this), amountToken);
// Transfer ETH to caller
payable(_msgSender()).transfer(amountETH);
return amountETH;
}
/**
* @notice Transfers tokens from sale reserve (`this`) to recipient (`recipient`)
* for the specified ETH amount at sale price (`salePriceETH`).
*
* @param recipient Recipient account.
* @param amountETH ETH amount (in wei).
*
* @return Token amount (in base units) transferred.
*/
function _commitSale(address recipient, uint256 amountETH) internal returns (uint256) {
require(amountETH > 0, "ETH amount is zero");
// Calculate token amount
uint256 amountToken = calcTokenFromETH(amountETH, salePriceETH);
require(amountToken > 0, "Token amount is zero");
// Transfer tokens to buyer
// NOTE: Fails if sale reserve (token balance of `this`) is exhausted
_transfer(address(this), recipient, amountToken);
return amountToken;
}
/**
* @notice Transfers tokens from sale reserve (`this`) to recipient (`recipient`)
* for the specified ETH amount at presale price (`presalePriceETH`).
*
* Credits presale buyback eligibility (`presaleBuybackEligibilityOf`) to
* caller for purchased token amount.
*
* If referrer (`referrer`) is non-zero, transfers referral reward,
* according to referral reward factor (`presaleReferralRewardFactor`)
* and the purchased token amount, from reward reserve (`rewardReserve`)
* to referrer. Referrer MAY NOT be the same as caller.
*
* @param recipient Recipient account.
* @param amountETH ETH amount (in wei).
* @param referer Referer account or zero.
*
* @return Token amount (in base units) transferred.
*/
function _commitPresale(
address recipient,
uint256 amountETH,
address referer
) internal returns (uint256) {
require(amountETH > 0, "ETH amount is zero");
require(referer != recipient, "Invalid referer");
// Calculate token amount
uint256 amountToken = calcTokenFromETH(amountETH, presalePriceETH);
require(amountToken > 0, "Token amount is zero");
// Credit presale buyback eligibility to recipient
_presaleBuybackEligibileToken[recipient] += amountToken;
// Transfer tokens to buyer
// NOTE: Fails if sale reserve (token balance of `this`) is exhausted
_transfer(address(this), recipient, amountToken);
// Query reward reserve token balance
uint256 rewardReserveBalanceToken = balanceOf(rewardReserve);
if (
referer != address(0) &&
presaleReferralRewardFactorPercent > 0 &&
rewardReserveBalanceToken > 0
) {
// Calculate referral reward token amount
uint256 referralRewardAmountToken = (amountToken * presaleReferralRewardFactorPercent) /
10000;
// Clamp referral reward token amount to reward reserve balance
if (referralRewardAmountToken > rewardReserveBalanceToken) {
referralRewardAmountToken = rewardReserveBalanceToken;
}
// Transfer referral reward
_transfer(rewardReserve, referer, referralRewardAmountToken);
}
return amountToken;
}
/**
* @notice Uniswap router.
*
* @dev Returns constant. Exists as a virtual method to facilitate testing.
*
* @return Uniswap router instance.
*/
function uniswapV2Router02() public view virtual returns (IUniswapV2Router02) {
return IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
}
/**
* @notice Emitted when sale resereve (`this`) is allocated via `allocateSaleReserve`.
*
* @param amountToken Token amount (in base units) allocated.
*/
event SaleReserveAllocated(uint256 amountToken);
/**
* @notice Transfers tokens from liquidity reserve (`liquidityReserve`) to
* sale reserve (`this`).
*
* ONLY avaiable to treasury caller (`treasury`) BEFORE sale
* ends (`saleEndTime`).
*/
function allocateSaleReserve(uint256 amountToken) external onlyTreasury onlyDuringSale {
_transfer(liquidityReserve, address(this), amountToken);
emit SaleReserveAllocated(amountToken);
}
/**
* @notice Emitted when sale resereve (`this`) is burned via `burnSaleReserve`.
*
* @param amountToken Token amount (in base units) burned.
*/
event SaleReserveBurned(uint256 amountToken);
/**
* @notice Burns all tokens on sale reserve (`this`).
*
* ONLY avaiable to treasury caller (`treasury`) AFTER sale
* ends (`saleEndTime`).
*/
function burnSaleReserve() external onlyTreasury onlyAfterSale {
uint256 saleReserveBalance = balanceOf(address(this));
_burn(address(this), saleReserveBalance);
emit SaleReserveBurned(saleReserveBalance);
}
/**
* @notice Emitted when a deposit is received via `deposit`.
*
* @param amountETH ETH amount (in wei).
*/
event DepositReceived(uint256 amountETH);
/**
* @notice Deposits ETH.
*
* ONLY avaiable to treasury caller (`treasury`).
*/
function deposit() external payable onlyTreasury {
emit DepositReceived(msg.value);
}
/**
* @notice Buys bridge tokens to the token account (`this`).
*
* ONLY avaiable to treasury caller (`treasury`).
*
* @param token Bridge token contract address.
* @param amountETH ETH amount (in wei) to spend.
*
* @return Token amount (in base units) transferred.
*/
function buyBridgeTokens(
UnigateBridgeToken token,
uint256 amountETH
) external onlyTreasury nonReentrant returns (uint256) {
require(token.masterToken() == address(this), "Invalid bridge token");
return token.buyTokensForETH{value: amountETH}();
}
/**
* @notice Sells bridge tokens from the token account (`this`).
*
* ONLY avaiable to treasury caller (`treasury`).
*
* @param token Bridge token contract address.
* @param amountToken Token amount (in base units) to sell.
*
* @return ETH amount (in wei) transferred.
*/
function sellBridgeTokens(
UnigateBridgeToken token,
uint256 amountToken
) external onlyTreasury nonReentrant returns (uint256) {
require(token.masterToken() == address(this), "Invalid bridge token");
return token.sellTokensForETH(amountToken);
}
/**
* @notice Specifies whether raw ETH receipt (via `receive`) is expected.
*
* Currently, only temporarily enabled for swap operations.
*/
bool private _expectReceive;
/**
* @notice Receives ETH.
*
* ONLY allowed when `_expectReceive` is truthy.
*/
receive() external payable {
require(_expectReceive, "Prohibited");
}
}
UnigateBridges.sol 134 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./Unigate.sol";
/**
* @title Unigate Treasury Bridge Token
* @author Unigate
* @notice Unigate Treasury bridge token contract.
*/
contract UnigateTreasuryBridgeToken is UnigateBridgeToken {
/**
* @notice Treasury address.
*/
address public immutable treasury;
/**
* @notice Price in ETH amount (in wei) for 1 token.
*/
uint256 public immutable priceETH;
/**
* @notice Initializes token parameters.
*
* @param treasury_ Treasury address.
* @param priceETH_ ETH amount (in wei) for 1 token.
* @param initialAllocationToken_ Initial allocation token amount (in base units).
* @param masterToken_ Master token contract address.
*/
constructor(
address treasury_,
uint256 priceETH_,
uint256 initialAllocationToken_,
address masterToken_
) UnigateBridgeToken("UnigateTreasuryBridge", "UGTT/T", masterToken_) {
// Set up treasury
require(treasury_ != address(0), "Treasury address is zero");
treasury = treasury_;
// Set up price
require(priceETH_ > 0, "Price is zero");
priceETH = priceETH_;
// Initial allocation
_mint(address(this), initialAllocationToken_);
}
/**
* @notice Checks that the caller (`_msgSender()`) is treasury (`treasury`).
*/
modifier onlyTreasury() {
require(_msgSender() == treasury, "Access denied");
_;
}
/**
* @notice Mints tokens to token reserve (`this`).
*
* ONLY avaiable to treasury caller (`treasury`).
*
* @param amountToken Token amount (in base units).
*/
function mint(uint256 amountToken) external onlyTreasury {
_mint(address(this), amountToken);
}
/**
* @notice Burns tokens from token reserve (`this`).
*
* ONLY avaiable to treasury caller (`treasury`).
*
* @param amountToken Token amount (in base units).
*/
function burn(uint256 amountToken) external onlyTreasury {
_burn(address(this), amountToken);
}
/**
* @notice Emitted when a deposit is received via `deposit`.
*
* @param amountETH ETH amount (in wei).
*/
event DepositReceived(uint256 amountETH);
/**
* @notice Deposits ETH.
*
* ONLY avaiable to treasury caller (`treasury`).
*/
function deposit() external payable onlyTreasury {
emit DepositReceived(msg.value);
}
/**
* @notice Emitted when a withdraw is completed via `withdraw`.
*
* @param amountETH ETH amount (in wei).
*/
event WithdrawCompleted(uint256 amountETH);
/**
* @notice Withdraws ETH.
*
* ONLY avaiable to treasury caller (`treasury`).
*
* @param amountETH ETH amount (in wei).
*/
function withdraw(uint256 amountETH) external onlyTreasury {
payable(_msgSender()).transfer(amountETH);
emit WithdrawCompleted(amountETH);
}
/**
* @notice Gets token price.
*
* @return ETH amount (in wei) for 1 token.
*/
function _priceETH() internal view override returns (uint256) {
return priceETH;
}
/**
* @notice Receives ETH.
*
* NOT ALLOWED.
*/
receive() external payable {
revert("Prohibited");
}
}
Read Contract
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
balanceOfRewardReserve 0xd5d0e9eb → uint256
balanceOfSaleReserve 0x191a4845 → uint256
calcETHFromToken 0xf75a854e → uint256
calcTokenFromETH 0xa1af3e5e → uint256
decimals 0x313ce567 → uint8
liquidityReserve 0xb753bfe9 → address
name 0x06fdde03 → string
presaleBuybackEligibilityOf 0x6a576112 → uint256
presaleBuybackEndTime 0x4020b317 → uint256
presaleEndTime 0x249b7c19 → uint256
presalePriceETH 0x4f5f21cf → uint256
presaleReferralRewardFactorPercent 0xd7e66d14 → uint256
rewardReserve 0xcab64bcd → address
saleEndTime 0xed338ff1 → uint256
salePriceETH 0x6b7cbf11 → uint256
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256
treasury 0x61d027b3 → address
uniswapV2Router02 0xa7c6402c → address
Write Contract 13 functions
These functions modify contract state and require a wallet transaction to execute.
allocateSaleReserve 0xc154b285
uint256 amountToken
approve 0x095ea7b3
address spender
uint256 value
returns: bool
burnSaleReserve 0x63e1289b
No parameters
buyBridgeTokens 0x4555a5aa
address token
uint256 amountETH
returns: uint256
buyTokensForETH 0x4632f560
No parameters
returns: uint256
buyTokensForTokens 0xc841c4af
address inputToken
uint256 amountInputToken
address[] swapPath
uint256 minAmountETH
returns: uint256
deposit 0xd0e30db0
No parameters
presaleBuyTokensForETH 0xbd977c75
address referer
returns: uint256
presaleBuyTokensForTokens 0x756c79db
address inputToken
uint256 amountInputToken
address[] swapPath
uint256 minAmountETH
address referer
returns: uint256
sellBridgeTokens 0x28a678b1
address token
uint256 amountToken
returns: uint256
sellPresaleBuybackTokensForETH 0xcc32d4da
uint256 amountToken
returns: uint256
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
Recent Transactions
No transactions found for this address