Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x9803E1Ee2ab1F0ad7F03e438d92B85402B5aB0Dd
Balance 0 ETH
Nonce 1
Code Size 9065 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9065 bytes
0x608060405260043610610191575f3560e01c8063a42dce80116100dc578063c58bfb6611610087578063d333555311610062578063d33355531461044b578063dc26777c1461046a578063f2fde38b14610489578063f887ea40146104a8575f80fd5b8063c58bfb6614610402578063cfa498a314610417578063d06ca61f1461042c575f80fd5b8063c0d78655116100b7578063c0d78655146103b0578063c415b95c146103cf578063c4ae3168146103ee575f80fd5b8063a42dce801461033f578063ad5c46481461035e578063ae06c1b714610391575f80fd5b80635c975abb1161013c5780638b5541f2116101175780638b5541f2146102dc5780638da5cb5b146102ef578063948c2ebf1461030b575f80fd5b80635c975abb14610285578063715018a6146102a75780638980f11f146102bd575f80fd5b80633a9361d11161016c5780633a9361d1146102325780634befe2ca1461025e5780635afb9bae14610272575f80fd5b80630cbab4f71461019c5780631f514c52146101ce57806337edee9a14610205575f80fd5b3661019857005b5f80fd5b3480156101a7575f80fd5b506101bb6101b6366004611e89565b6104cc565b6040519081526020015b60405180910390f35b3480156101d9575f80fd5b506003546101ed906001600160a01b031681565b6040516001600160a01b0390911681526020016101c5565b348015610210575f80fd5b5061022461021f366004611ea0565b6104ee565b6040516101c5929190611f52565b34801561023d575f80fd5b5061025161024c366004611f8e565b6107a1565b6040516101c59190611fc4565b348015610269575f80fd5b506101bb606481565b34801561027d575f80fd5b506101bb5f81565b348015610290575f80fd5b5060025460ff1660405190151581526020016101c5565b3480156102b2575f80fd5b506102bb610d44565b005b3480156102c8575f80fd5b506102bb6102d7366004611fd6565b610d57565b6101bb6102ea366004611ffe565b610e0a565b3480156102fa575f80fd5b505f546001600160a01b03166101ed565b348015610316575f80fd5b5061032a61032536600461202e565b611290565b604080519283526020830191909152016101c5565b34801561034a575f80fd5b506102bb610359366004612058565b611405565b348015610369575f80fd5b506101ed7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b34801561039c575f80fd5b506102bb6103ab366004611e89565b6114cd565b3480156103bb575f80fd5b506102bb6103ca366004612058565b61156b565b3480156103da575f80fd5b506004546101ed906001600160a01b031681565b3480156103f9575f80fd5b506102bb611639565b34801561040d575f80fd5b506101bb60055481565b348015610422575f80fd5b506101bb61271081565b348015610437575f80fd5b50610251610446366004611ea0565b61165c565b348015610456575f80fd5b506102bb610465366004611e89565b6116d7565b348015610475575f80fd5b50610251610484366004612071565b611719565b348015610494575f80fd5b506102bb6104a3366004612058565b611c37565b3480156104b3575f80fd5b506002546101ed9061010090046001600160a01b031681565b5f612710600554836104de91906120bf565b6104e891906120d6565b92915050565b6003546060905f9081906001600160a01b0316858561050e6001826120f5565b81811061051d5761051d612108565b90506020020160208101906105329190612058565b6003546001600160a01b039182169290921492505f91168686838161055957610559612108565b905060200201602081019061056e9190612058565b6001600160a01b03161490505f600260019054906101000a90046001600160a01b03166001600160a01b031663d06ca61f8989896040518463ffffffff1660e01b81526004016105c09392919061211c565b5f60405180830381865afa1580156105da573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106019190810190612185565b905081156106f357610612886104cc565b93505f61061f858a6120f5565b905080156106a75760025460405163d06ca61f60e01b81526101009091046001600160a01b03169063d06ca61f9061065f9084908c908c9060040161211c565b5f60405180830381865afa158015610679573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526106a09190810190612185565b95506106ed565b8667ffffffffffffffff8111156106c0576106c0612171565b6040519080825280602002602001820160405280156106e9578160200160208202803683370190505b5095505b50610796565b821561078f5780945061072b816001835161070e91906120f5565b8151811061071e5761071e612108565b60200260200101516104cc565b935083816001835161073d91906120f5565b8151811061074d5761074d612108565b602002602001015161075f91906120f5565b856001875161076e91906120f5565b8151811061077e5761077e612108565b602002602001018181525050610796565b8094505f93505b505050935093915050565b60606107ab611c74565b6107b3611ccd565b6001600160a01b03851661080e5760405162461bcd60e51b815260206004820152601860248201527f496e76616c696420746f6b656e20696e2061646472657373000000000000000060448201526064015b60405180910390fd5b6003546001600160a01b039081169086160361086c5760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742073776170205649525455414c20666f7220697473656c6600006044820152606401610805565b6040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038616906323b872dd906064016020604051808303815f875af11580156108bc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108e0919061223e565b506040805160028082526060820183525f9260208301908036833701905050905085815f8151811061091457610914612108565b6001600160a01b03928316602091820292909201015260035482519116908290600190811061094557610945612108565b6001600160a01b03928316602091820292909201015260025460405163095ea7b360e01b815261010090910482166004820152602481018790529087169063095ea7b3906044016020604051808303815f875af11580156109a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109cc919061223e565b506003546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa158015610a13573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a37919061225d565b600254604051635c11d79560e01b815291925061010090046001600160a01b031690635c11d79590610a759089905f90879030908b906004016122ac565b5f604051808303815f87803b158015610a8c575f80fd5b505af1158015610a9e573d5f803e3d5ffd5b50506003546040516370a0823160e01b81523060048201525f93506001600160a01b0390911691506370a0823190602401602060405180830381865afa158015610aea573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b0e919061225d565b90505f610b1b83836120f5565b90505f610b27826104cc565b90505f610b3482846120f5565b905088811015610b865760405162461bcd60e51b815260206004820152601a60248201527f496e73756666696369656e74206f757470757420616d6f756e740000000000006044820152606401610805565b6003546004805460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018590529091169063a9059cbb906044016020604051808303815f875af1158015610bdc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c00919061223e565b5060035460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303815f875af1158015610c4f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c73919061223e565b506040805160028082526060820183525f926020830190803683370190505090508a815f81518110610ca757610ca7612108565b6020026020010181815250508181600181518110610cc757610cc7612108565b602090810291909101810191909152600354604080518e815292830185905282018590526001600160a01b0390811691908e169033907f78144de69c30989060d6bc0b4e6da9a31b6497866db952e683d0221e9cd20165906060015b60405180910390a49650505050505050610d3c60018055565b949350505050565b610d4c611d20565b610d555f611d4c565b565b610d5f611d20565b816001600160a01b031663a9059cbb610d7f5f546001600160a01b031690565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303815f875af1158015610de1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e05919061223e565b505050565b5f610e13611c74565b610e1b611ccd565b6001600160a01b038416610e715760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420746f6b656e206f75742061646472657373000000000000006044820152606401610805565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316846001600160a01b031603610ef25760405162461bcd60e51b815260206004820181905260248201527f55736520444558206469726563746c7920666f722045544820746f20574554486044820152606401610805565b5f3411610f415760405162461bcd60e51b815260206004820152600d60248201527f4d7573742073656e6420455448000000000000000000000000000000000000006044820152606401610805565b5f610f4b346104cc565b90505f610f5882346120f5565b90505f8111610fa95760405162461bcd60e51b815260206004820152601660248201527f46656520657863656564732045544820616d6f756e74000000000000000000006044820152606401610805565b6004546040515f916001600160a01b03169084908381818185875af1925050503d805f8114610ff3576040519150601f19603f3d011682016040523d82523d5f602084013e610ff8565b606091505b50509050806110495760405162461bcd60e51b815260206004820152601360248201527f466565207472616e73666572206661696c6564000000000000000000000000006044820152606401610805565b6040805160028082526060820183525f926020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2815f8151811061109c5761109c612108565b60200260200101906001600160a01b031690816001600160a01b03168152505087816001815181106110d0576110d0612108565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523360048201525f918a16906370a0823190602401602060405180830381865afa158015611122573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611146919061225d565b60025460405163b6f9de9560e01b815291925061010090046001600160a01b03169063b6f9de95908690611184908c90879033908e906004016122e7565b5f604051808303818588803b15801561119b575f80fd5b505af11580156111ad573d5f803e3d5ffd5b50506040516370a0823160e01b81523360048201525f93506001600160a01b038d1692506370a082319150602401602060405180830381865afa1580156111f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061121a919061225d565b90505f61122783836120f5565b60408051348152602081018390529081018990529091506001600160a01b038c169033907f4aa9f44c127958d1ecc5cd03cd596505f6810b90f8c7d9633c826e2659160a079060600160405180910390a3965050505050505061128960018055565b9392505050565b6040805160028082526060820183525f928392839290916020830190803683370190505090507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2815f815181106112e9576112e9612108565b60200260200101906001600160a01b031690816001600160a01b031681525050838160018151811061131d5761131d612108565b60200260200101906001600160a01b031690816001600160a01b031681525050611346856104cc565b91505f61135383876120f5565b905080156113f85760025460405163d06ca61f60e01b81525f9161010090046001600160a01b03169063d06ca61f90611392908590879060040161231b565b5f60405180830381865afa1580156113ac573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113d39190810190612185565b9050806001815181106113e8576113e8612108565b60200260200101519450506113fc565b5f93505b50509250929050565b61140d611d20565b6001600160a01b03811661146f5760405162461bcd60e51b8152602060048201526024808201527f46656520636f6c6c6563746f722063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610805565b600480546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f5d16ad41baeb009cd23eb8f6c7cde5c2e0cd5acf4a33926ab488875c37c37f38905f90a35050565b6114d5611d20565b60648111156115265760405162461bcd60e51b815260206004820152600c60248201527f46656520746f6f206869676800000000000000000000000000000000000000006044820152606401610805565b600580549082905560408051828152602081018490527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a15050565b611573611d20565b6001600160a01b0381166115c95760405162461bcd60e51b815260206004820152601d60248201527f526f757465722063616e6e6f74206265207a65726f20616464726573730000006044820152606401610805565b600280546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161790945560405193909204169182907f02dc5c233404867c793b749c6d644beb2277536d18a7e7974d3f238e4c6f1684905f90a35050565b611641611d20565b60025460ff161561165457610d55611da8565b610d55611dfa565b60025460405163d06ca61f60e01b815260609161010090046001600160a01b03169063d06ca61f906116969087908790879060040161211c565b5f60405180830381865afa1580156116b0573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d3c9190810190612185565b6116df611d20565b5f80546040516001600160a01b039091169183156108fc02918491818181858888f19350505050158015611715573d5f803e3d5ffd5b5050565b6060611723611c74565b61172b611ccd565b6001600160a01b0383166117815760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420746f6b656e206f75742061646472657373000000000000006044820152606401610805565b6003546001600160a01b03908116908416036117df5760405162461bcd60e51b815260206004820152601e60248201527f43616e6e6f742073776170205649525455414c20666f7220697473656c6600006044820152606401610805565b5f6117e9866104cc565b90505f6117f682886120f5565b90505f81116118475760405162461bcd60e51b815260206004820152601860248201527f466565206578636565647320696e70757420616d6f756e7400000000000000006044820152606401610805565b6003546040516323b872dd60e01b8152336004820152306024820152604481018990526001600160a01b03909116906323b872dd906064016020604051808303815f875af115801561189b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118bf919061223e565b506003546004805460405163a9059cbb60e01b81526001600160a01b0391821692810192909252602482018590529091169063a9059cbb906044016020604051808303815f875af1158015611916573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061193a919061223e565b506040805160028082526060820183525f92602083019080368337505060035482519293506001600160a01b0316918391505f9061197a5761197a612108565b60200260200101906001600160a01b031690816001600160a01b03168152505085816001815181106119ae576119ae612108565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523360048201525f918816906370a0823190602401602060405180830381865afa158015611a00573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a24919061225d565b60035460025460405163095ea7b360e01b81526001600160a01b036101009092048216600482015260248101879052929350169063095ea7b3906044016020604051808303815f875af1158015611a7d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611aa1919061223e565b50600254604051635c11d79560e01b81526101009091046001600160a01b031690635c11d79590611ade9086908c90879033908d906004016122ac565b5f604051808303815f87803b158015611af5575f80fd5b505af1158015611b07573d5f803e3d5ffd5b50506040516370a0823160e01b81523360048201525f92506001600160a01b038a1691506370a0823190602401602060405180830381865afa158015611b4f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b73919061225d565b90505f611b8083836120f5565b6040805160028082526060820183529293505f9290916020830190803683370190505090508b815f81518110611bb857611bb8612108565b6020026020010181815250508181600181518110611bd857611bd8612108565b602090810291909101810191909152600354604080518f815292830185905282018990526001600160a01b03808d169291169033907f78144de69c30989060d6bc0b4e6da9a31b6497866db952e683d0221e9cd2016590606001610d23565b611c3f611d20565b6001600160a01b038116611c6857604051631e4fbdf760e01b81525f6004820152602401610805565b611c7181611d4c565b50565b600260015403611cc65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610805565b6002600155565b60025460ff1615610d555760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610805565b5f546001600160a01b03163314610d555760405163118cdaa760e01b8152336004820152602401610805565b5f80546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b611db0611e37565b6002805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b611e02611ccd565b6002805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611ddd3390565b60025460ff16610d555760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610805565b5f60208284031215611e99575f80fd5b5035919050565b5f805f60408486031215611eb2575f80fd5b83359250602084013567ffffffffffffffff80821115611ed0575f80fd5b818601915086601f830112611ee3575f80fd5b813581811115611ef1575f80fd5b8760208260051b8501011115611f05575f80fd5b6020830194508093505050509250925092565b5f815180845260208085019450602084015f5b83811015611f4757815187529582019590820190600101611f2b565b509495945050505050565b604081525f611f646040830185611f18565b90508260208301529392505050565b80356001600160a01b0381168114611f89575f80fd5b919050565b5f805f8060808587031215611fa1575f80fd5b611faa85611f73565b966020860135965060408601359560600135945092505050565b602081525f6112896020830184611f18565b5f8060408385031215611fe7575f80fd5b611ff083611f73565b946020939093013593505050565b5f805f60608486031215612010575f80fd5b61201984611f73565b95602085013595506040909401359392505050565b5f806040838503121561203f575f80fd5b8235915061204f60208401611f73565b90509250929050565b5f60208284031215612068575f80fd5b61128982611f73565b5f805f8060808587031215612084575f80fd5b843593506020850135925061209b60408601611f73565b9396929550929360600135925050565b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176104e8576104e86120ab565b5f826120f057634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156104e8576104e86120ab565b634e487b7160e01b5f52603260045260245ffd5b838152604060208083018290529082018390525f90849060608401835b86811015612165576001600160a01b0361215285611f73565b1682529282019290820190600101612139565b50979650505050505050565b634e487b7160e01b5f52604160045260245ffd5b5f6020808385031215612196575f80fd5b825167ffffffffffffffff808211156121ad575f80fd5b818501915085601f8301126121c0575f80fd5b8151818111156121d2576121d2612171565b8060051b604051601f19603f830116810181811085821117156121f7576121f7612171565b604052918252848201925083810185019188831115612214575f80fd5b938501935b8285101561223257845184529385019392850192612219565b98975050505050505050565b5f6020828403121561224e575f80fd5b81518015158114611289575f80fd5b5f6020828403121561226d575f80fd5b5051919050565b5f815180845260208085019450602084015f5b83811015611f475781516001600160a01b031687529582019590820190600101612287565b85815284602082015260a060408201525f6122ca60a0830186612274565b6001600160a01b0394909416606083015250608001529392505050565b848152608060208201525f6122ff6080830186612274565b6001600160a01b03949094166040830152506060015292915050565b828152604060208201525f610d3c604083018461227456fea2646970667358221220cc7d3ddbdec3a52e18e72ad51bf95d9eda3a95f02de00fd1f688da6ec0b52e7a64736f6c63430008190033

Verified Source Code Partial Match

Compiler: v0.8.25+commit.b61c2a91 EVM: cancun Optimization: Yes (800 runs)
TRUSTSWAP.sol 771 lines
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

/**
 * @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;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @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 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;

    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
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // 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;
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)


/**
 * @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);
}

// File: contracts/TrustSwap.sol

interface IUniswapV2Router {
    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 WETH() external pure returns (address);
    
    function getAmountsOut(
        uint amountIn, 
        address[] calldata path
    ) external view returns (uint[] memory amounts);
}

contract TRUSTSWAP is Ownable, ReentrancyGuard, Pausable {
    IUniswapV2Router public router;
    address public virtualToken;
    address public feeCollector;
    address public immutable WETH;
    
    // Fee settings
    uint256 public platformFeeBasisPoints = 25; // 0.25% fee (25/10000)
    uint256 public constant BASIS_POINTS_DENOMINATOR = 10000;
    uint256 public constant MIN_FEE_BASIS_POINTS = 0;
    uint256 public constant MAX_FEE_BASIS_POINTS = 100;
    
    // Events
    event TokensSwapped(
        address indexed user,
        address indexed tokenIn,
        address indexed tokenOut,
        uint256 amountIn,
        uint256 amountOut,
        uint256 feeAmount
    );
    
    event ETHSwapped(
        address indexed user,
        address indexed tokenOut,
        uint256 ethAmount,
        uint256 tokenAmount,
        uint256 feeAmount
    );
    
    event FeeCollectorUpdated(address indexed oldCollector, address indexed newCollector);
    event RouterUpdated(address indexed oldRouter, address indexed newRouter);
    event FeeUpdated(uint256 oldFee, uint256 newFee);
    
    constructor(
        address _router,
        address _virtualToken,
        address _feeCollector
    ) Ownable(msg.sender) {
        require(_router != address(0), "Router cannot be zero address");
        require(_virtualToken != address(0), "Virtual token cannot be zero address");
        require(_feeCollector != address(0), "Fee collector cannot be zero address");
        
        router = IUniswapV2Router(_router);
        virtualToken = _virtualToken;
        feeCollector = _feeCollector;
        WETH = router.WETH();
    }
    
    // Admin functions
    function setRouter(address _router) external onlyOwner {
        require(_router != address(0), "Router cannot be zero address");
        address oldRouter = address(router);
        router = IUniswapV2Router(_router);
        emit RouterUpdated(oldRouter, _router);
    }
    
    function setFeeCollector(address _feeCollector) external onlyOwner {
        require(_feeCollector != address(0), "Fee collector cannot be zero address");
        address oldCollector = feeCollector;
        feeCollector = _feeCollector;
        emit FeeCollectorUpdated(oldCollector, _feeCollector);
    }
    
    function setFeePercentage(uint256 _newFeeBasisPoints) external onlyOwner {
        require(_newFeeBasisPoints >= MIN_FEE_BASIS_POINTS, "Fee too low");
        require(_newFeeBasisPoints <= MAX_FEE_BASIS_POINTS, "Fee too high");
        
        uint256 oldFee = platformFeeBasisPoints;
        platformFeeBasisPoints = _newFeeBasisPoints;
        emit FeeUpdated(oldFee, _newFeeBasisPoints);
    }
    
    function togglePause() external onlyOwner {
        if (paused()) {
            _unpause();
        } else {
            _pause();
        }
    }
    
    // View functions
    function calculatePlatformFee(uint256 amount) public view returns (uint256) {
        return (amount * platformFeeBasisPoints) / BASIS_POINTS_DENOMINATOR;
    }
    
    function getAmountsOut(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory) {
        return router.getAmountsOut(amountIn, path);
    }
    
    // Get expected output amounts with fee deducted (for UI purposes)
    function getAmountsOutWithFee(
        uint256 amountIn,
        address[] calldata path
    ) external view returns (uint256[] memory amounts, uint256 feeAmount) {
        // Check if this is a swap to or from VIRTUAL
        bool isToVirtual = path[path.length - 1] == virtualToken;
        bool isFromVirtual = path[0] == virtualToken;
        
        uint256[] memory rawAmounts = router.getAmountsOut(amountIn, path);
        
        if (isFromVirtual) {
            // When buying with VIRTUAL, fee is taken from input
            feeAmount = calculatePlatformFee(amountIn);
            // Calculate output with reduced input
            uint256 amountInAfterFee = amountIn - feeAmount;
            if (amountInAfterFee > 0) {
                amounts = router.getAmountsOut(amountInAfterFee, path);
            } else {
                // If fee consumes all input, return zeros
                amounts = new uint256[](path.length);
            }
        } else if (isToVirtual) {
            // When selling for VIRTUAL, fee is taken from output
            amounts = rawAmounts;
            feeAmount = calculatePlatformFee(rawAmounts[rawAmounts.length - 1]);
            // Adjust final output after fee
            amounts[amounts.length - 1] = rawAmounts[rawAmounts.length - 1] - feeAmount;
        } else {
            // Non-VIRTUAL swaps - still charge fee in VIRTUAL (must be handled separately)
            amounts = rawAmounts;
            feeAmount = 0; // Fee must be supplied separately in VIRTUAL
        }
        
        return (amounts, feeAmount);
    }
    
    // Get ETH to token amounts with fee calculation (for UI purposes)
    function getETHToTokenAmountsWithFee(
        uint256 ethAmountIn,
        address tokenOut
    ) external view returns (uint256 expectedTokens, uint256 feeAmountETH) {
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = tokenOut;
        
        // Calculate fee in ETH
        feeAmountETH = calculatePlatformFee(ethAmountIn);
        uint256 ethAmountAfterFee = ethAmountIn - feeAmountETH;
        
        // Get expected tokens with reduced ETH input
        if (ethAmountAfterFee > 0) {
            uint256[] memory amountsAfterFee = router.getAmountsOut(ethAmountAfterFee, path);
            expectedTokens = amountsAfterFee[1];
        } else {
            expectedTokens = 0;
        }
        
        return (expectedTokens, feeAmountETH);
    }
    
    // Simplified function for buying with VIRTUAL (fee taken from input)
    function swapVirtualWithFee(
        uint256 amountIn,
        uint256 amountOutMin,
        address tokenOut,
        uint256 deadline
    ) external nonReentrant whenNotPaused returns (uint256[] memory) {
        require(tokenOut != address(0), "Invalid token out address");
        require(tokenOut != virtualToken, "Cannot swap VIRTUAL for itself");
        
        // Calculate fee
        uint256 feeAmount = calculatePlatformFee(amountIn);
        uint256 amountInAfterFee = amountIn - feeAmount;
        
        require(amountInAfterFee > 0, "Fee exceeds input amount");
        
        // Transfer total amount from user (includes fee)
        IERC20(virtualToken).transferFrom(msg.sender, address(this), amountIn);
        
        // Transfer fee to fee collector
        IERC20(virtualToken).transfer(feeCollector, feeAmount);
        
        // Prepare path
        address[] memory path = new address[](2);
        path[0] = virtualToken;
        path[1] = tokenOut;
        
        // Record balance before swap
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(msg.sender);
        
        // Approve router to spend VIRTUAL
        IERC20(virtualToken).approve(address(router), amountInAfterFee);
        
        // Execute swap
        router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amountInAfterFee,
            amountOutMin,
            path,
            msg.sender,
            deadline
        );
        
        // Calculate output amount
        uint256 balanceAfter = IERC20(tokenOut).balanceOf(msg.sender);
        uint256 amountOut = balanceAfter - balanceBefore;
        
        // Prepare return amounts
        uint256[] memory amounts = new uint256[](2);
        amounts[0] = amountIn;
        amounts[1] = amountOut;
        
        emit TokensSwapped(
            msg.sender,
            virtualToken,
            tokenOut,
            amountIn,
            amountOut,
            feeAmount
        );
        
        return amounts;
    }
    
    // Simplified function for selling for VIRTUAL (fee taken from output)
    function swapForVirtualWithFee(
        address tokenIn,
        uint256 amountIn,
        uint256 amountOutMin,
        uint256 deadline
    ) external nonReentrant whenNotPaused returns (uint256[] memory) {
        require(tokenIn != address(0), "Invalid token in address");
        require(tokenIn != virtualToken, "Cannot swap VIRTUAL for itself");
        
        // Transfer input tokens from user
        IERC20(tokenIn).transferFrom(msg.sender, address(this), amountIn);
        
        // Prepare path
        address[] memory path = new address[](2);
        path[0] = tokenIn;
        path[1] = virtualToken;
        
        // Approve router to spend input tokens
        IERC20(tokenIn).approve(address(router), amountIn);
        
        // Record VIRTUAL balance before swap
        uint256 balanceBefore = IERC20(virtualToken).balanceOf(address(this));
        
        // Execute swap to contract first
        router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amountIn,
            0, // We'll check minimum output manually
            path,
            address(this),
            deadline
        );
        
        // Calculate received amount
        uint256 balanceAfter = IERC20(virtualToken).balanceOf(address(this));
        uint256 totalReceived = balanceAfter - balanceBefore;
        
        // Calculate fee
        uint256 feeAmount = calculatePlatformFee(totalReceived);
        uint256 amountToSend = totalReceived - feeAmount;
        
        // Check minimum output requirement
        require(amountToSend >= amountOutMin, "Insufficient output amount");
        
        // Transfer fee to fee collector
        IERC20(virtualToken).transfer(feeCollector, feeAmount);
        
        // Transfer remaining amount to user
        IERC20(virtualToken).transfer(msg.sender, amountToSend);
        
        // Prepare return amounts
        uint256[] memory amounts = new uint256[](2);
        amounts[0] = amountIn;
        amounts[1] = amountToSend;
        
        emit TokensSwapped(
            msg.sender,
            tokenIn,
            virtualToken,
            amountIn,
            amountToSend,
            feeAmount
        );
        
        return amounts;
    }
    
    // New function: Swap ETH for tokens with fee
    function swapETHForTokensWithFee(
        address tokenOut,
        uint256 amountOutMin,
        uint256 deadline
    ) external payable nonReentrant whenNotPaused returns (uint256) {
        require(tokenOut != address(0), "Invalid token out address");
        require(tokenOut != WETH, "Use DEX directly for ETH to WETH");
        require(msg.value > 0, "Must send ETH");
        
        // Calculate fee in ETH
        uint256 feeAmount = calculatePlatformFee(msg.value);
        uint256 swapAmount = msg.value - feeAmount;
        
        require(swapAmount > 0, "Fee exceeds ETH amount");
        
        // Transfer ETH fee to fee collector
        (bool feeSent, ) = payable(feeCollector).call{value: feeAmount}("");
        require(feeSent, "Fee transfer failed");
        
        // Prepare path
        address[] memory path = new address[](2);
        path[0] = WETH;
        path[1] = tokenOut;
        
        // Record balance before swap
        uint256 balanceBefore = IERC20(tokenOut).balanceOf(msg.sender);
        
        // Execute swap with remaining ETH
        router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: swapAmount}(
            amountOutMin,
            path,
            msg.sender,
            deadline
        );
        
        // Calculate output amount
        uint256 balanceAfter = IERC20(tokenOut).balanceOf(msg.sender);
        uint256 amountOut = balanceAfter - balanceBefore;
        
        emit ETHSwapped(
            msg.sender,
            tokenOut,
            msg.value,
            amountOut,
            feeAmount
        );
        
        return amountOut;
    }
    
    // Emergency function to recover any tokens accidentally sent to the contract
    function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
        IERC20(tokenAddress).transfer(owner(), tokenAmount);
    }
    
    // Emergency function to recover ETH accidentally sent to the contract
    function recoverETH(uint256 amount) external onlyOwner {
        payable(owner()).transfer(amount);
    }
    
    // Required to receive ETH from swaps
    receive() external payable {}
}

Read Contract

BASIS_POINTS_DENOMINATOR 0xcfa498a3 → uint256
MAX_FEE_BASIS_POINTS 0x4befe2ca → uint256
MIN_FEE_BASIS_POINTS 0x5afb9bae → uint256
WETH 0xad5c4648 → address
calculatePlatformFee 0x0cbab4f7 → uint256
feeCollector 0xc415b95c → address
getAmountsOut 0xd06ca61f → uint256[]
getAmountsOutWithFee 0x37edee9a → uint256[], uint256
getETHToTokenAmountsWithFee 0x948c2ebf → uint256, uint256
owner 0x8da5cb5b → address
paused 0x5c975abb → bool
platformFeeBasisPoints 0xc58bfb66 → uint256
router 0xf887ea40 → address
virtualToken 0x1f514c52 → address

Write Contract 11 functions

These functions modify contract state and require a wallet transaction to execute.

recoverERC20 0x8980f11f
address tokenAddress
uint256 tokenAmount
recoverETH 0xd3335553
uint256 amount
renounceOwnership 0x715018a6
No parameters
setFeeCollector 0xa42dce80
address _feeCollector
setFeePercentage 0xae06c1b7
uint256 _newFeeBasisPoints
setRouter 0xc0d78655
address _router
swapETHForTokensWithFee 0x8b5541f2
address tokenOut
uint256 amountOutMin
uint256 deadline
returns: uint256
swapForVirtualWithFee 0x3a9361d1
address tokenIn
uint256 amountIn
uint256 amountOutMin
uint256 deadline
returns: uint256[]
swapVirtualWithFee 0xdc26777c
uint256 amountIn
uint256 amountOutMin
address tokenOut
uint256 deadline
returns: uint256[]
togglePause 0xc4ae3168
No parameters
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address