Address Contract Partially Verified
Address
0x9803E1Ee2ab1F0ad7F03e438d92B85402B5aB0Dd
Balance
0 ETH
Nonce
1
Code Size
9065 bytes
Creator
0xC1A2f762...dbaF at tx 0x001ba5f7...a42c99
Indexed Transactions
0
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