Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0x480ea104fF7063Ed0Af41c98d8EF2457afE2a41c
Balance 0 ETH
Nonce 1
Code Size 21006 bytes
Last Active
Indexed Transactions 1 (10,634,74910,634,749)
Gas Used (indexed) 4,610,479
External Etherscan · Sourcify

Contract Bytecode

21006 bytes
0x60806040526004361061003f5760003560e01c8063085e2c5b1461004e5780638373f265146100f8578063e2a7515e146101af578063fbe4ed9514610289575b3332141561004c57600080fd5b005b34801561005a57600080fd5b5061009d600480360360a081101561007157600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356102ba565b6040518083815260200180602001828103825283818151815260200191508051906020019060200280838360005b838110156100e35781810151838201526020016100cb565b50505050905001935050505060405180910390f35b34801561010457600080fd5b5061014d600480360360c081101561011b57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a001356102dd565b6040518084815260200183815260200180602001828103825283818151815260200191508051906020019060200280838360005b83811015610199578181015183820152602001610181565b5050505090500194505050505060405180910390f35b610277600480360360c08110156101c557600080fd5b6001600160a01b03823581169260208101359091169160408201359160608101359181019060a081016080820135600160201b81111561020457600080fd5b82018360208201111561021657600080fd5b803590602001918460208302840111600160201b8311171561023757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250610434915050565b60408051918252519081900360200190f35b34801561029557600080fd5b5061029e61080d565b604080516001600160a01b039092168252519081900360200190f35b600060606102cd878787878760006102dd565b9199919850909650505050505050565b6000805460408051638373f26560e01b81526001600160a01b038a81166004830152898116602483015260448201899052606482018890526084820187905260a48201869052915184936060931691638373f2659160c48083019287929190829003018186803b15801561035057600080fd5b505afa158015610364573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052606081101561038d57600080fd5b81516020830151604080850180519151939592948301929184600160201b8211156103b757600080fd5b9083019060208201858111156103cc57600080fd5b82518660208202830111600160201b821117156103e857600080fd5b82525081516020918201928201910280838360005b838110156104155781810151838201526020016103fd565b5050505090500160405250505092509250925096509650969350505050565b6000856001600160a01b0316876001600160a01b03161415610457575083610803565b61045f61503a565b60405180610440016040528061081c8152602001610aa88152602001610af58152602001610e3b8152602001611104815260200161129a815260200161147681526020016116a681526020016118e08152602001611b1a8152602001611dc38152602001611feb81526020016123478152602001612560815260200161256c815260200161258781526020016125a281526020016125bd81526020016127f781526020016129848152602001612b788152602001612c248152602001612cfb8152602001612d9a8152602001612f8e8152602001612f9c8152602001612faa8152602001612fb88152602001612fd58152602001612feb815260200161300b8152602001613021815260200161303b81526020016130db81525090506022845111156105bc5760405162461bcd60e51b81526004018080602001828103825260428152602001806151986042913960600191505060405180910390fd5b600080805b865181101561061a5760008782815181106105d857fe5b602002602001015111156106125761060c8782815181106105f557fe5b60200260200101518461314990919063ffffffff16565b92508091505b6001016105c1565b508161067a576106328a6001600160a01b03166131ac565b1561066f5760405133903480156108fc02916000818181858888f19350505050158015610663573d6000803e3d6000fd5b50349350505050610803565b879350505050610803565b6106956001600160a01b038b1633308b63ffffffff6131e516565b60006106b06001600160a01b038c163063ffffffff6132f716565b905060005b8751811015610753578781815181106106ca57fe5b6020026020010151600014156106df5761074b565b60006107178561070b8b85815181106106f457fe5b60200260200101518e6133a190919063ffffffff16565b9063ffffffff6133fa16565b9050838214156107245750815b80830392506107498d8d838b8a876022811061073c57fe5b602002015163ffffffff16565b505b6001016106b5565b5061076d6001600160a01b038b163063ffffffff6132f716565b9450878510156107ae5760405162461bcd60e51b81526004018080602001828103825260268152602001806151126026913960400191505060405180910390fd5b6107c86001600160a01b038b16338763ffffffff61343c16565b506107fd336107e66001600160a01b038e163063ffffffff6132f716565b6001600160a01b038e16919063ffffffff61343c16565b50505050505b9695505050505050565b6000546001600160a01b031681565b8161082f6001600160a01b0386166131ac565b61096f57604080516303795fb160e11b81526001600160a01b0387166004820152905160009173c0a47dfe034b400b47bdad5fecda2621de6c4d95916306f2bf6291602480820192602092909190829003018186803b15801561089157600080fd5b505afa1580156108a5573d6000803e3d6000fd5b505050506040513d60208110156108bb57600080fd5b505190506001600160a01b0381161561096d576108e86001600160a01b038716828463ffffffff6134ba16565b604080516395e3c50b60e01b8152600481018490526001602482015242604482015290516001600160a01b038316916395e3c50b9160648083019260209291908290030181600087803b15801561093e57600080fd5b505af1158015610952573d6000803e3d6000fd5b505050506040513d602081101561096857600080fd5b505191505b505b610981846001600160a01b03166131ac565b610aa157604080516303795fb160e11b81526001600160a01b0386166004820152905160009173c0a47dfe034b400b47bdad5fecda2621de6c4d95916306f2bf6291602480820192602092909190829003018186803b1580156109e357600080fd5b505afa1580156109f7573d6000803e3d6000fd5b505050506040513d6020811015610a0d57600080fd5b505190506001600160a01b03811615610a9f57806001600160a01b031663f39b5b9b836001426040518463ffffffff1660e01b815260040180838152602001828152602001925050506020604051808303818588803b158015610a6f57600080fd5b505af1158015610a83573d6000803e3d6000fd5b50505050506040513d6020811015610a9a57600080fd5b505191505b505b5050505050565b6040805162461bcd60e51b815260206004820152601a60248201527f5468697320736f75726365207761732064657072656361746564000000000000604482015290519081900360640190fd5b60007352ae12abe5d8bd778bd5397f99ca900624cfadd46001600160a01b031663bb34534c6040518163ffffffff1660e01b815260040180806c42616e636f724e6574776f726b60981b815250602001905060206040518083038186803b158015610b5f57600080fd5b505afa158015610b73573d6000803e3d6000fd5b505050506040513d6020811015610b8957600080fd5b505190506060736f0cd8c4f6f06eab664c7e3031909452b4b728616375e1cc82610bbb6001600160a01b0389166131ac565b610bc55787610bdb565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3155b610bed886001600160a01b03166131ac565b610bf75787610c0d565b73c0829421c1d260bd3cb3e0f06cfe2d52db2ce3155b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060006040518083038186803b158015610c6c57600080fd5b505afa158015610c80573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610ca957600080fd5b8101908080516040519392919084600160201b821115610cc857600080fd5b908301906020820185811115610cdd57600080fd5b82518660208202830111600160201b82111715610cf957600080fd5b82525081516020918201928201910280838360005b83811015610d26578181015183820152602001610d0e565b505050509050016040525050509050610d538285886001600160a01b03166134ba9092919063ffffffff16565b816001600160a01b031663f3898a97610d74886001600160a01b03166131ac565b610d7f576000610d81565b855b838760016040518563ffffffff1660e01b81526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015610de0578181015183820152602001610dc8565b505050509050019450505050506020604051808303818588803b158015610e0657600080fd5b505af1158015610e1a573d6000803e3d6000fd5b50505050506040513d6020811015610e3157600080fd5b5050505050505050565b610e4d846001600160a01b03166131ac565b15610eb5576000805160206150668339815191526001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015610e9b57600080fd5b505af1158015610eaf573d6000803e3d6000fd5b50505050505b6000610ec9856001600160a01b03166131ac565b610ed35784610ee3565b6000805160206150668339815191525b9050610f136001600160a01b03821673794e6e91555438afc3ccf1c5076a74f42133d08d8563ffffffff6134ba16565b73794e6e91555438afc3ccf1c5076a74f42133d08d630621b4f6610f3f6001600160a01b0388166131ac565b610f495786610f59565b6000805160206150668339815191525b85610f6c886001600160a01b03166131ac565b610f765787610f86565b6000805160206150668339815191525b604080516001600160e01b031960e087901b1681526001600160a01b03948516600482015260248101939093529216604482015260016064820152905160848083019260209291908290030181600087803b158015610fe457600080fd5b505af1158015610ff8573d6000803e3d6000fd5b505050506040513d602081101561100e57600080fd5b5061102390506001600160a01b0385166131ac565b15610aa157604080516370a0823160e01b8152306004820152905160008051602061506683398151915291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b15801561107b57600080fd5b505afa15801561108f573d6000803e3d6000fd5b505050506040513d60208110156110a557600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b1580156110e557600080fd5b505af11580156110f9573d6000803e3d6000fd5b505050505050505050565b60006001600160a01b0385166000805160206150f28339815191521461112b57600061112e565b60025b6001600160a01b03861660008051602061508683398151915214611153576000611156565b60015b0160ff16905060006000805160206150f28339815191526001600160a01b03861614611183576000611186565b60025b6001600160a01b038616600080516020615086833981519152146111ab5760006111ae565b60015b0160ff16905081600f0b600014806111c9575080600f0b6000145b156111d5575050611294565b6112036001600160a01b03871673a2b47e3d5c44877cca798226b7b8118f9bfb7a568663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b602482015260448101869052600060648201819052915173a2b47e3d5c44877cca798226b7b8118f9bfb7a569263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b505af115801561128d573d6000803e3d6000fd5b5050505050505b50505050565b60006001600160a01b03851673dac17f958d2ee523a2206206994597c13d831ec7146112c75760006112ca565b60035b6001600160a01b0386166000805160206150f2833981519152146112ef5760006112f2565b60025b6001600160a01b0387166000805160206150868339815191521461131757600061131a565b60015b010160ff169050600073dac17f958d2ee523a2206206994597c13d831ec76001600160a01b0316856001600160a01b03161461135757600061135a565b60035b6001600160a01b0386166000805160206150f28339815191521461137f576000611382565b60025b6001600160a01b038716600080516020615086833981519152146113a75760006113aa565b60015b010160ff16905081600f0b600014806113c6575080600f0b6000145b156113d2575050611294565b6114006001600160a01b0387167352ea46506b9cc5ef470c5bf89f17dc28bb35d85c8663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b60248201526044810186905260006064820181905291517352ea46506b9cc5ef470c5bf89f17dc28bb35d85c9263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b60006001600160a01b0385166e085d4780b73119b644ae5ecd22b3761461149e5760006114a1565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec7146114cc5760006114cf565b60035b6001600160a01b0387166000805160206150f2833981519152146114f45760006114f7565b60025b6001600160a01b0388166000805160206150868339815191521461151c57600061151f565b60015b01010160ff16905060006e085d4780b73119b644ae5ecd22b3766001600160a01b0316856001600160a01b03161461155857600061155b565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec714611586576000611589565b60035b6001600160a01b0387166000805160206150f2833981519152146115ae5760006115b1565b60025b6001600160a01b038816600080516020615086833981519152146115d65760006115d9565b60015b01010160ff16905081600f0b600014806115f6575080600f0b6000145b15611602575050611294565b6116306001600160a01b0387167345f783cce6b7ff23b2ab2d70e416cdb7d6055f518663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b60248201526044810186905260006064820181905291517345f783cce6b7ff23b2ab2d70e416cdb7d6055f519263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b60006001600160a01b038516734fabb145d64652a948d72533023f6e7a623c7c53146116d35760006116d6565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec714611701576000611704565b60035b6001600160a01b0387166000805160206150f28339815191521461172957600061172c565b60025b6001600160a01b03881660008051602061508683398151915214611751576000611754565b60015b01010160ff1690506000734fabb145d64652a948d72533023f6e7a623c7c536001600160a01b0316856001600160a01b031614611792576000611795565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec7146117c05760006117c3565b60035b6001600160a01b0387166000805160206150f2833981519152146117e85760006117eb565b60025b6001600160a01b03881660008051602061508683398151915214611810576000611813565b60015b01010160ff16905081600f0b60001480611830575080600f0b6000145b1561183c575050611294565b61186a6001600160a01b0387167379a8c46dea5ada233abaffd40f3a0a2b1e5a4f278663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b60248201526044810186905260006064820181905291517379a8c46dea5ada233abaffd40f3a0a2b1e5a4f279263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b60006001600160a01b0385167357ab1ec28d129707052df4df418d58a2d46d5f511461190d576000611910565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec71461193b57600061193e565b60035b6001600160a01b0387166000805160206150f283398151915214611963576000611966565b60025b6001600160a01b0388166000805160206150868339815191521461198b57600061198e565b60015b01010160ff16905060007357ab1ec28d129707052df4df418d58a2d46d5f516001600160a01b0316856001600160a01b0316146119cc5760006119cf565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec7146119fa5760006119fd565b60035b6001600160a01b0387166000805160206150f283398151915214611a22576000611a25565b60025b6001600160a01b03881660008051602061508683398151915214611a4a576000611a4d565b60015b01010160ff16905081600f0b60001480611a6a575080600f0b6000145b15611a76575050611294565b611aa46001600160a01b03871673a5407eae9ba41422680e2e00537571bcc53efbfd8663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b602482015260448101869052600060648201819052915173a5407eae9ba41422680e2e00537571bcc53efbfd9263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b611b2c846001600160a01b03166131ac565b611c7357604080516332a5d5bf60e01b81526001600160a01b0386166004820152905160009173f451dbd7ba14bfa7b1b78a766d3ed438f79ee1d1916332a5d5bf91602480820192602092909190829003018186803b158015611b8e57600080fd5b505afa158015611ba2573d6000803e3d6000fd5b505050506040513d6020811015611bb857600080fd5b50519050611bd66001600160a01b038616828563ffffffff6134ba16565b806001600160a01b031663a0712d68846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015611c1c57600080fd5b505af1158015611c30573d6000803e3d6000fd5b505050506040513d6020811015611c4657600080fd5b50611c6d90508185611c676001600160a01b0383163063ffffffff6132f716565b8561081c565b50611294565b611c85836001600160a01b03166131ac565b61129457604080516332a5d5bf60e01b81526001600160a01b0385166004820152905160009173f451dbd7ba14bfa7b1b78a766d3ed438f79ee1d1916332a5d5bf91602480820192602092909190829003018186803b158015611ce757600080fd5b505afa158015611cfb573d6000803e3d6000fd5b505050506040513d6020811015611d1157600080fd5b50519050611d218582858561081c565b6001600160a01b03811663db006a75611d40823063ffffffff6132f716565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015611d7657600080fd5b505af1158015611d8a573d6000803e3d6000fd5b505050506040513d6020811015611da057600080fd5b50611dbc90506001600160a01b0385163063ffffffff6132f716565b5050611294565b6001600160a01b0384166000805160206150868339815191521415611eb857611e106001600160a01b0385167306af07097c9eeb7fd685c692751d5c66db49c2158463ffffffff6134ba16565b60408051633b4da69f60e01b81523060048201526024810184905290517306af07097c9eeb7fd685c692751d5c66db49c21591633b4da69f91604480830192600092919082900301818387803b158015611e6957600080fd5b505af1158015611e7d573d6000803e3d6000fd5b50611eb392507306af07097c9eeb7fd685c692751d5c66db49c2159150859050611ead823063ffffffff6132f716565b8461081c565b611294565b6001600160a01b038316600080516020615086833981519152141561129457611ef7847306af07097c9eeb7fd685c692751d5c66db49c215848461081c565b604080516370a0823160e01b8152306004820181905291517306af07097c9eeb7fd685c692751d5c66db49c2159263ef693bed92909184916370a08231916024808301926020929190829003018186803b158015611f5457600080fd5b505afa158015611f68573d6000803e3d6000fd5b505050506040513d6020811015611f7e57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b039093166004840152602483019190915251604480830192600092919082900301818387803b158015611fce57600080fd5b505af1158015611fe2573d6000803e3d6000fd5b50505050611294565b611ffd846001600160a01b03166131ac565b6121c35760408051635f5418f360e01b81526001600160a01b0386166004820152905160009173ed8b133b7b88366e01bb9e38305ab11c2652149491635f5418f391602480820192602092909190829003018186803b15801561205f57600080fd5b505afa158015612073573d6000803e3d6000fd5b505050506040513d602081101561208957600080fd5b50516040805163797a759360e11b815290519192506121209173398ec7346dcd622edc5ae82352f02be94c62d1199163f2f4eb26916004808301926020929190829003018186803b1580156120dd57600080fd5b505afa1580156120f1573d6000803e3d6000fd5b505050506040513d602081101561210757600080fd5b50516001600160a01b038716908563ffffffff6134ba16565b60408051636968703360e11b81526001600160a01b03871660048201526024810185905261044d6044820152905173398ec7346dcd622edc5ae82352f02be94c62d1199163d2d0e06691606480830192600092919082900301818387803b15801561218a57600080fd5b505af115801561219e573d6000803e3d6000fd5b50505050611c6d8185611c6730856001600160a01b03166132f790919063ffffffff16565b6121d5836001600160a01b03166131ac565b6112945760408051635f5418f360e01b81526001600160a01b0385166004820152905160009173ed8b133b7b88366e01bb9e38305ab11c2652149491635f5418f391602480820192602092909190829003018186803b15801561223757600080fd5b505afa15801561224b573d6000803e3d6000fd5b505050506040513d602081101561226157600080fd5b505190506122718582858561081c565b604080516370a0823160e01b815230600482015290516001600160a01b0383169163db006a759183916370a08231916024808301926020929190829003018186803b1580156122bf57600080fd5b505afa1580156122d3573d6000803e3d6000fd5b505050506040513d60208110156122e957600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561232957600080fd5b505af115801561233d573d6000803e3d6000fd5b5050505050611294565b60007371cd6666064c3a1354a3b4dca5fa1e2d3ee7d30363901754d76123756001600160a01b0388166131ac565b61237f5786612382565b60005b612394876001600160a01b03166131ac565b61239e57866123a1565b60005b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b03168152602001826001600160a01b03166001600160a01b031681526020019250505060206040518083038186803b15801561240057600080fd5b505afa158015612414573d6000803e3d6000fd5b505050506040513d602081101561242a57600080fd5b505190506124486001600160a01b038616828563ffffffff6134ba16565b806001600160a01b031663d5bcb9b5612469876001600160a01b03166131ac565b612474576000612476565b845b612488886001600160a01b03166131ac565b6124925787612495565b60005b6124a7886001600160a01b03166131ac565b6124b157876124b4565b60005b604080516001600160e01b031960e087901b1681526001600160a01b03938416600482015291909216602482015260448101889052600060648201527368a17b587caf4f9329f0e372e3a78d23a46de6b56084820152905160a480830192602092919082900301818588803b15801561252c57600080fd5b505af1158015612540573d6000803e3d6000fd5b50505050506040513d602081101561255757600080fd5b50505050505050565b610aa1848484846135b3565b61129484600080516020615066833981519152858585613a47565b61129484600080516020615086833981519152858585613a47565b611294846000805160206150f2833981519152858585613a47565b60006001600160a01b038516738e870d67f660d95d5be530380d0ec0bd388289e1146125ea5760006125ed565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec71461261857600061261b565b60035b6001600160a01b0387166000805160206150f283398151915214612640576000612643565b60025b6001600160a01b0388166000805160206150868339815191521461266857600061266b565b60015b01010160ff1690506000738e870d67f660d95d5be530380d0ec0bd388289e16001600160a01b0316856001600160a01b0316146126a95760006126ac565b60045b6001600160a01b03861673dac17f958d2ee523a2206206994597c13d831ec7146126d75760006126da565b60035b6001600160a01b0387166000805160206150f2833981519152146126ff576000612702565b60025b6001600160a01b0388166000805160206150868339815191521461272757600061272a565b60015b01010160ff16905081600f0b60001480612747575080600f0b6000145b15612753575050611294565b6127816001600160a01b0387167306364f10b501e868329afbc005b3492902d6c7638663ffffffff6134ba16565b60408051635320bf6b60e11b8152600019808501600f90810b810b6004840152908401810b900b60248201526044810186905260006064820181905291517306364f10b501e868329afbc005b3492902d6c7639263a6417ed6926084808201939182900301818387803b15801561127957600080fd5b60006001600160a01b038516732260fac5e5542a773aa44fbcfedf7c193bc2c59914612824576000612827565b60025b6001600160a01b03861673eb4c2781e4eba804ce9a9803c67d0893436bb27d14612852576000612855565b60015b0160ff1690506000732260fac5e5542a773aa44fbcfedf7c193bc2c5996001600160a01b0386161461288857600061288b565b60025b6001600160a01b03861673eb4c2781e4eba804ce9a9803c67d0893436bb27d146128b65760006128b9565b60015b0160ff16905081600f0b600014806128d4575080600f0b6000145b156128e0575050611294565b61290e6001600160a01b0387167393054188d876f558f4a66b2ef1d97d16edf0895b8663ffffffff6134ba16565b60408051630f7c084960e21b8152600019808501600f90810b810b6004840152908401810b900b60248201526044810186905260006064820181905291517393054188d876f558f4a66b2ef1d97d16edf0895b92633df02124926084808201939182900301818387803b15801561127957600080fd5b60006001600160a01b038516730316eb71485b0ab14103307bf65a021042c6d380146129b15760006129b4565b60035b6001600160a01b038616732260fac5e5542a773aa44fbcfedf7c193bc2c599146129df5760006129e2565b60025b6001600160a01b038716731bbe271d15bb64df0bc6cd28df9ff322f2ebd84714612a0d576000612a10565b60015b010160ff1690506000730316eb71485b0ab14103307bf65a021042c6d3806001600160a01b0316856001600160a01b031614612a4d576000612a50565b60035b6001600160a01b038616732260fac5e5542a773aa44fbcfedf7c193bc2c59914612a7b576000612a7e565b60025b6001600160a01b038716731bbe271d15bb64df0bc6cd28df9ff322f2ebd84714612aa9576000612aac565b60015b010160ff16905081600f0b60001480612ac8575080600f0b6000145b15612ad4575050611294565b612b026001600160a01b038716739726e9314ef1b96e45f40056bed61a088897313e8663ffffffff6134ba16565b60408051630f7c084960e21b8152600019808501600f90810b810b6004840152908401810b900b6024820152604481018690526000606482018190529151739726e9314ef1b96e45f40056bed61a088897313e92633df02124926084808201939182900301818387803b15801561127957600080fd5b612ba66001600160a01b0385167303ef3f37856bd08eb47e2de7abc4ddd2c19b60f28463ffffffff6134ba16565b60408051630df791e560e41b81526001600160a01b038681166004830152851660248201526044810184905290517303ef3f37856bd08eb47e2de7abc4ddd2c19b60f29163df791e5091606480830192600092919082900301818387803b158015612c1057600080fd5b505af1158015610e31573d6000803e3d6000fd5b612c526001600160a01b03851673a8253a440be331dc4a7395b73948cca6f19dc97d8463ffffffff6134ba16565b604080516303ff4c0160e31b81526001600160a01b0386811660048301528516602482015260448101849052600060648201819052603242016084830152915173a8253a440be331dc4a7395b73948cca6f19dc97d92631ffa60089260a480820193602093909283900390910190829087803b158015612cd157600080fd5b505af1158015612ce5573d6000803e3d6000fd5b505050506040513d6020811015610a9f57600080fd5b612d296001600160a01b03851673e2f2a5c287993345a840db3b0845fbc70f5935a58463ffffffff6134ba16565b60408051631ba0488760e21b81526001600160a01b0386811660048301528516602482015260448101849052306064820152905173e2f2a5c287993345a840db3b0845fbc70f5935a591636e81221c9160848083019260209291908290030181600087803b158015612cd157600080fd5b60006001600160a01b03851673fe18be6b3bd88a2d2a7f928d00292e7a9963cfc614612dc7576000612dca565b60035b6001600160a01b038616732260fac5e5542a773aa44fbcfedf7c193bc2c59914612df5576000612df8565b60025b6001600160a01b03871673eb4c2781e4eba804ce9a9803c67d0893436bb27d14612e23576000612e26565b60015b010160ff169050600073fe18be6b3bd88a2d2a7f928d00292e7a9963cfc66001600160a01b0316856001600160a01b031614612e63576000612e66565b60035b6001600160a01b038616732260fac5e5542a773aa44fbcfedf7c193bc2c59914612e91576000612e94565b60025b6001600160a01b03871673eb4c2781e4eba804ce9a9803c67d0893436bb27d14612ebf576000612ec2565b60015b010160ff16905081600f0b60001480612ede575080600f0b6000145b15612eea575050611294565b612f186001600160a01b038716737fc77b5c7614e1533320ea6ddc2eb61fa00a97148663ffffffff6134ba16565b60408051630f7c084960e21b8152600019808501600f90810b810b6004840152908401810b900b6024820152604481018690526000606482018190529151737fc77b5c7614e1533320ea6ddc2eb61fa00a971492633df02124926084808201939182900301818387803b15801561127957600080fd5b611294848484846000613a5e565b611294848484846001613a5e565b611294848484846002613a5e565b611294848484846001685a434ecd46efdcc7c760b11b0319613ecf565b61129484848484600161543360e81b0319613ecf565b6112948484848460016b2c2466af65a2f7eba2a7a463609a1b0319613ecf565b6112948484848461301c89896146ff565b613ecf565b61302e8460008484612347565b6112946000844784612347565b613055846000805160206150868339815191528484612347565b604080516370a0823160e01b815230600482015290516112949160008051602061508683398151915291869183916370a0823191602480820192602092909190829003018186803b1580156130a957600080fd5b505afa1580156130bd573d6000803e3d6000fd5b505050506040513d60208110156130d357600080fd5b505184612347565b6130f5846000805160206150f28339815191528484612347565b604080516370a0823160e01b81523060048201529051611294916000805160206150f283398151915291869183916370a0823191602480820192602092909190829003018186803b1580156130a957600080fd5b6000828201838110156131a3576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b60006001600160a01b03821615806131a657506001600160a01b03821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b806131ef57611294565b6131f8846131ac565b156132dc576001600160a01b038316331480156132155750803410155b6132505760405162461bcd60e51b815260040180806020018281038252602b8152602001806150a6602b913960400191505060405180910390fd5b6001600160a01b0382163014613298576040516001600160a01b0383169082156108fc029083906000818181858888f19350505050158015613296573d6000803e3d6000fd5b505b80341115611eb357336108fc6132b4348463ffffffff61497a16565b6040518115909202916000818181858888f19350505050158015611c6d573d6000803e3d6000fd5b6112946001600160a01b03851684848463ffffffff6149bc16565b6000613302836131ac565b1561331857506001600160a01b038116316131a6565b826001600160a01b03166370a08231836040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561336e57600080fd5b505afa158015613382573d6000803e3d6000fd5b505050506040513d602081101561339857600080fd5b505190506131a6565b6000826133b0575060006131a6565b828202828482816133bd57fe5b04146131a35760405162461bcd60e51b81526004018080602001828103825260218152602001806150d16021913960400191505060405180910390fd5b60006131a383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614a16565b60008161344b575060016134b3565b613454846131ac565b15613495576040516001600160a01b0384169083156108fc029084906000818181858888f1935050505015801561348f573d6000803e3d6000fd5b506134b3565b6134af6001600160a01b038516848463ffffffff614ab816565b5060015b9392505050565b6134c3836131ac565b6135ae57806134ec576134e76001600160a01b03841683600063ffffffff614b0a16565b6135ae565b60408051636eb1769f60e11b81523060048201526001600160a01b038481166024830152915160009286169163dd62ed3e916044808301926020929190829003018186803b15801561353d57600080fd5b505afa158015613551573d6000803e3d6000fd5b505050506040513d602081101561356757600080fd5b5051905081811015611294578015613594576135946001600160a01b03851684600063ffffffff614b0a16565b6112946001600160a01b038516848463ffffffff614b0a16565b505050565b60006135c7856001600160a01b03166131ac565b1561362f576000805160206150668339815191526001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b15801561361557600080fd5b505af1158015613629573d6000803e3d6000fd5b50505050505b6000613643866001600160a01b03166131ac565b61364d578561365d565b6000805160206150668339815191525b90506000613673866001600160a01b03166131ac565b61367d578561368d565b6000805160206150668339815191525b6040805163e6a4390560e01b81526001600160a01b038581166004830152831660248201529051919250600091735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f9163e6a43905916044808301926020929190829003018186803b1580156136f557600080fd5b505afa158015613709573d6000803e3d6000fd5b505050506040513d602081101561371f57600080fd5b505190506000806137416001600160a01b03841686868b63ffffffff614c1d16565b9197509250905081156137a657826001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561378957600080fd5b505af115801561379d573d6000803e3d6000fd5b50505050613820565b8015613820576040805163bc25cf7760e01b81527368a17b587caf4f9329f0e372e3a78d23a46de6b5600482015290516001600160a01b0385169163bc25cf7791602480830192600092919082900301818387803b15801561380757600080fd5b505af115801561381b573d6000803e3d6000fd5b505050505b61383a6001600160a01b038616848a63ffffffff61343c16565b50836001600160a01b0316856001600160a01b031610156138d3576040805163022c0d9f60e01b815260006004820181905260248201899052306044830152608060648301526084820181905291516001600160a01b0386169263022c0d9f9260c4808201939182900301818387803b1580156138b657600080fd5b505af11580156138ca573d6000803e3d6000fd5b5050505061394d565b6040805163022c0d9f60e01b815260048101889052600060248201819052306044830152608060648301526084820181905291516001600160a01b0386169263022c0d9f9260c4808201939182900301818387803b15801561393457600080fd5b505af1158015613948573d6000803e3d6000fd5b505050505b61395f896001600160a01b03166131ac565b15613a3a57604080516370a0823160e01b8152306004820152905160008051602061506683398151915291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b1580156139b757600080fd5b505afa1580156139cb573d6000803e3d6000fd5b505050506040513d60208110156139e157600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b158015613a2157600080fd5b505af1158015613a35573d6000803e3d6000fd5b505050505b5050505050949350505050565b610a9f8484613a58888887876135b3565b846135b3565b60607365e67cbc342712df67494acefc06fe951ee9398263bfdbfc43613a8c6001600160a01b0389166131ac565b613a965787613aa6565b6000805160206150668339815191525b613ab8886001600160a01b03166131ac565b613ac25787613ad2565b6000805160206150668339815191525b856001016040518463ffffffff1660e01b815260040180846001600160a01b03166001600160a01b03168152602001836001600160a01b03166001600160a01b03168152602001828152602001935050505060006040518083038186803b158015613b3c57600080fd5b505afa158015613b50573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015613b7957600080fd5b8101908080516040519392919084600160201b821115613b9857600080fd5b908301906020820185811115613bad57600080fd5b82518660208202830111600160201b82111715613bc957600080fd5b82525081516020918201928201910280838360005b83811015613bf6578181015183820152602001613bde565b505050509050016040525050509050613c17866001600160a01b03166131ac565b15613c7f576000805160206150668339815191526001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015613c6557600080fd5b505af1158015613c79573d6000803e3d6000fd5b50505050505b613cd9818381518110613c8e57fe5b602002602001015185613ca9896001600160a01b03166131ac565b613cb35788613cc3565b6000805160206150668339815191525b6001600160a01b0316919063ffffffff6134ba16565b808281518110613ce557fe5b60200260200101516001600160a01b0316638201aa3f613d0d886001600160a01b03166131ac565b613d175787613d27565b6000805160206150668339815191525b86613d3a896001600160a01b03166131ac565b613d445788613d54565b6000805160206150668339815191525b60006000196040518663ffffffff1660e01b815260040180866001600160a01b03166001600160a01b03168152602001858152602001846001600160a01b03166001600160a01b03168152602001838152602001828152602001955050505050506040805180830381600087803b158015613dce57600080fd5b505af1158015613de2573d6000803e3d6000fd5b505050506040513d6040811015613df857600080fd5b50613e0d90506001600160a01b0386166131ac565b15610a9f57604080516370a0823160e01b8152306004820152905160008051602061506683398151915291632e1a7d4d9183916370a08231916024808301926020929190829003018186803b158015613e6557600080fd5b505afa158015613e79573d6000803e3d6000fd5b505050506040513d6020811015613e8f57600080fd5b5051604080516001600160e01b031960e085901b168152600481019290925251602480830192600092919082900301818387803b15801561127957600080fd5b604080516001808252818301909252849160609190602080830190803883390190505090508281600081518110613f0257fe5b602002602001018181525050613f20876001600160a01b03166131ac565b61432157606073a1c0fa73c39cfbcc11ec9eb1afc665aba9996e2c6001600160a01b03166361e597f9896001856000604051908082528060200260200182016040528015613f78578160200160208202803883390190505b506040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b03168152602001846003811115613fb057fe5b60ff1681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015613ff8578181015183820152602001613fe0565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561403757818101518382015260200161401f565b50505050905001965050505050505060006040518083038186803b15801561405e57600080fd5b505afa158015614072573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561409b57600080fd5b8101908080516040519392919084600160201b8211156140ba57600080fd5b9083019060208201858111156140cf57600080fd5b8251600160201b8111828201881017156140e857600080fd5b82525081516020918201929091019080838360005b838110156141155781810151838201526020016140fd565b50505050905090810190601f1680156141425780820380516001836020036101000a031916815260200191505b506040525091925061417b9150506001600160a01b038916739aab3f75489902f3a48495025729a0af77d4b11e8863ffffffff6134ba16565b739aab3f75489902f3a48495025729a0af77d4b11e6001600160a01b031663ae591d54898573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee3060001960007368a17b587caf4f9329f0e372e3a78d23a46de6b560ff8e901c600a028a6040518a63ffffffff1660e01b8152600401808a6001600160a01b03166001600160a01b03168152602001898152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001868152602001858152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561429d578181015183820152602001614285565b50505050905090810190601f1680156142ca5780820380516001836020036101000a031916815260200191505b509a5050505050505050505050602060405180830381600087803b1580156142f157600080fd5b505af1158015614305573d6000803e3d6000fd5b505050506040513d602081101561431b57600080fd5b50519250505b614333866001600160a01b03166131ac565b61255757606073a1c0fa73c39cfbcc11ec9eb1afc665aba9996e2c6001600160a01b03166381efcbdd88600185600060405190808252806020026020018201604052801561438b578160200160208202803883390190505b506040518563ffffffff1660e01b815260040180856001600160a01b03166001600160a01b031681526020018460038111156143c357fe5b60ff1681526020018060200180602001838103835285818151815260200191508051906020019060200280838360005b8381101561440b5781810151838201526020016143f3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561444a578181015183820152602001614432565b50505050905001965050505050505060006040518083038186803b15801561447157600080fd5b505afa158015614485573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156144ae57600080fd5b8101908080516040519392919084600160201b8211156144cd57600080fd5b9083019060208201858111156144e257600080fd5b8251600160201b8111828201881017156144fb57600080fd5b82525081516020918201929091019080838360005b83811015614528578181015183820152602001614510565b50505050905090810190601f1680156145555780820380516001836020036101000a031916815260200191505b506040525050509050739aab3f75489902f3a48495025729a0af77d4b11e6001600160a01b031663ae591d548473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee868b3060001960007368a17b587caf4f9329f0e372e3a78d23a46de6b560ff8f901c600a028b6040518b63ffffffff1660e01b8152600401808a6001600160a01b03166001600160a01b03168152602001898152602001886001600160a01b03166001600160a01b03168152602001876001600160a01b03166001600160a01b03168152602001868152602001858152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614681578181015183820152602001614669565b50505050905090810190601f1680156146ae5780820380516001836020036101000a031916815260200191505b509a50505050505050505050506020604051808303818588803b1580156146d457600080fd5b505af11580156146e8573d6000803e3d6000fd5b50505050506040513d602081101561128d57600080fd5b6000614713836001600160a01b03166131ac565b15801561472f575061472d826001600160a01b03166131ac565b155b1561473c575060006131a6565b606073c8fb12402cb16970f3c5f4b48ff68eb9d1289301633d3dc52c61476a6001600160a01b0387166131ac565b6147745785614776565b845b6040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060006040518083038186803b1580156147bc57600080fd5b505afa1580156147d0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156147f957600080fd5b8101908080516040519392919084600160201b82111561481857600080fd5b90830190602082018581111561482d57600080fd5b82518660208202830111600160201b8211171561484957600080fd5b82525081516020918201928201910280838360005b8381101561487657818101518382015260200161485e565b50505050905001604052505050905060008090505b815181101561496f5760f88282815181106148a257fe5b602002602001015160001c901c60bb141580156148e557508181815181106148c657fe5b60200260200101516001685a434ecd46efdcc7c760b11b031960001b14155b801561491057508181815181106148f857fe5b6020026020010151600161543360e81b031960001b14155b8015614945575081818151811061492357fe5b602002602001015160016b2c2466af65a2f7eba2a7a463609a1b031960001b14155b156149675781818151811061495657fe5b6020026020010151925050506131a6565b60010161488b565b506000949350505050565b60006131a383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614dd6565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611294908590614e30565b60008183614aa25760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614a67578181015183820152602001614a4f565b50505050905090810190601f168015614a945780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614aae57fe5b0495945050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526135ae908490614e30565b801580614b90575060408051636eb1769f60e11b81523060048201526001600160a01b03848116602483015291519185169163dd62ed3e91604480820192602092909190829003018186803b158015614b6257600080fd5b505afa158015614b76573d6000803e3d6000fd5b505050506040513d6020811015614b8c57600080fd5b5051155b614bcb5760405162461bcd60e51b81526004018080602001828103825260368152602001806151626036913960400191505060405180910390fd5b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b1790526135ae908490614e30565b6000808080614c3b6001600160a01b0388168963ffffffff6132f716565b90506000614c586001600160a01b0388168a63ffffffff6132f716565b90506000808a6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015614c9657600080fd5b505afa158015614caa573d6000803e3d6000fd5b505050506040513d6060811015614cc057600080fd5b50805160209091015190925090506001600160a01b03808a16908b161115614ce457905b816001600160701b0316841080614d035750806001600160701b031683105b955085158015614d2d5750816001600160701b0316841180614d2d5750806001600160701b031683115b94506000614d43896103e563ffffffff6133a116565b90506000614d6a614d5d86856001600160701b0316614fe8565b839063ffffffff6133a116565b90506000614da383614d976103e8614d8b8b8a6001600160701b0316614fe8565b9063ffffffff6133a116565b9063ffffffff61314916565b90508015614dc057614dbb828263ffffffff6133fa16565b614dc3565b60005b9950505050505050509450945094915050565b60008184841115614e285760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614a67578181015183820152602001614a4f565b505050900390565b614e42826001600160a01b0316614ffe565b614e93576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b60208310614ed15780518252601f199092019160209182019101614eb2565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114614f33576040519150601f19603f3d011682016040523d82523d6000602084013e614f38565b606091505b509150915081614f8f576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561129457808060200190516020811015614fab57600080fd5b50516112945760405162461bcd60e51b815260040180806020018281038252602a815260200180615138602a913960400191505060405180910390fd5b6000818310614ff757816131a3565b5090919050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081811480159061503257508115155b949350505050565b6040518061044001604052806022905b61506381526020019060019003908161504a5790505090565bfefe000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f57726f6e6720757365616765206f66204554482e756e6976657273616c5472616e7366657246726f6d2829536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb484f6e6553706c69743a2052657475726e20616d6f756e7420776173206e6f7420656e6f7567685361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565645361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f20746f206e6f6e2d7a65726f20616c6c6f77616e63654f6e6553706c69743a20446973747269627574696f6e2061727261792073686f756c64206e6f74206578636565642072657365727665732061727261792073697a65a265627a7a72315820a7810b563a2b3b8d2c6de6f3026721a61f47df98505f5574f26361201e0559cf64736f6c63430005110032

Verified Source Code Partial Match

Compiler: v0.5.17+commit.d19bba13 EVM: istanbul Optimization: Yes (200 runs)
OneSplit.sol 7108 lines
// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

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

// File: contracts/IOneSplit.sol

pragma solidity ^0.5.0;


//
//  [ msg.sender ]
//       | |
//       | |
//       \_/
// +---------------+ ________________________________
// | OneSplitAudit | _______________________________  \
// +---------------+                                 \ \
//       | |                      ______________      | | (staticcall)
//       | |                    /  ____________  \    | |
//       | | (call)            / /              \ \   | |
//       | |                  / /               | |   | |
//       \_/                  | |               \_/   \_/
// +--------------+           | |           +----------------------+
// | OneSplitWrap |           | |           |   OneSplitViewWrap   |
// +--------------+           | |           +----------------------+
//       | |                  | |                     | |
//       | | (delegatecall)   | | (staticcall)        | | (staticcall)
//       \_/                  | |                     \_/
// +--------------+           | |             +------------------+
// |   OneSplit   |           | |             |   OneSplitView   |
// +--------------+           | |             +------------------+
//       | |                  / /
//        \ \________________/ /
//         \__________________/
//


contract IOneSplitConsts {
    // flags = FLAG_DISABLE_UNISWAP + FLAG_DISABLE_BANCOR + ...
    uint256 internal constant FLAG_DISABLE_UNISWAP = 0x01;
    uint256 internal constant DEPRECATED_FLAG_DISABLE_KYBER = 0x02; // Deprecated
    uint256 internal constant FLAG_DISABLE_BANCOR = 0x04;
    uint256 internal constant FLAG_DISABLE_OASIS = 0x08;
    uint256 internal constant FLAG_DISABLE_COMPOUND = 0x10;
    uint256 internal constant FLAG_DISABLE_FULCRUM = 0x20;
    uint256 internal constant FLAG_DISABLE_CHAI = 0x40;
    uint256 internal constant FLAG_DISABLE_AAVE = 0x80;
    uint256 internal constant FLAG_DISABLE_SMART_TOKEN = 0x100;
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_ETH = 0x200; // Deprecated, Turned off by default
    uint256 internal constant FLAG_DISABLE_BDAI = 0x400;
    uint256 internal constant FLAG_DISABLE_IEARN = 0x800;
    uint256 internal constant FLAG_DISABLE_CURVE_COMPOUND = 0x1000;
    uint256 internal constant FLAG_DISABLE_CURVE_USDT = 0x2000;
    uint256 internal constant FLAG_DISABLE_CURVE_Y = 0x4000;
    uint256 internal constant FLAG_DISABLE_CURVE_BINANCE = 0x8000;
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_DAI = 0x10000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_USDC = 0x20000; // Deprecated, Turned off by default
    uint256 internal constant FLAG_DISABLE_CURVE_SYNTHETIX = 0x40000;
    uint256 internal constant FLAG_DISABLE_WETH = 0x80000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_COMPOUND = 0x100000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH
    uint256 internal constant FLAG_DISABLE_UNISWAP_CHAI = 0x200000; // Works only when ETH<>DAI or FLAG_ENABLE_MULTI_PATH_ETH
    uint256 internal constant FLAG_DISABLE_UNISWAP_AAVE = 0x400000; // Works only when one of assets is ETH or FLAG_ENABLE_MULTI_PATH_ETH
    uint256 internal constant FLAG_DISABLE_IDLE = 0x800000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP = 0x1000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_V2 = 0x2000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_V2_ETH = 0x4000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_V2_DAI = 0x8000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_V2_USDC = 0x10000000;
    uint256 internal constant FLAG_DISABLE_ALL_SPLIT_SOURCES = 0x20000000;
    uint256 internal constant FLAG_DISABLE_ALL_WRAP_SOURCES = 0x40000000;
    uint256 internal constant FLAG_DISABLE_CURVE_PAX = 0x80000000;
    uint256 internal constant FLAG_DISABLE_CURVE_RENBTC = 0x100000000;
    uint256 internal constant FLAG_DISABLE_CURVE_TBTC = 0x200000000;
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_USDT = 0x400000000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_WBTC = 0x800000000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_TBTC = 0x1000000000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_RENBTC = 0x2000000000; // Deprecated, Turned off by default
    uint256 internal constant FLAG_DISABLE_DFORCE_SWAP = 0x4000000000;
    uint256 internal constant FLAG_DISABLE_SHELL = 0x8000000000;
    uint256 internal constant FLAG_ENABLE_CHI_BURN = 0x10000000000;
    uint256 internal constant FLAG_DISABLE_MSTABLE_MUSD = 0x20000000000;
    uint256 internal constant FLAG_DISABLE_CURVE_SBTC = 0x40000000000;
    uint256 internal constant FLAG_DISABLE_DMM = 0x80000000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_ALL = 0x100000000000;
    uint256 internal constant FLAG_DISABLE_CURVE_ALL = 0x200000000000;
    uint256 internal constant FLAG_DISABLE_UNISWAP_V2_ALL = 0x400000000000;
    uint256 internal constant FLAG_DISABLE_SPLIT_RECALCULATION = 0x800000000000;
    uint256 internal constant FLAG_DISABLE_BALANCER_ALL = 0x1000000000000;
    uint256 internal constant FLAG_DISABLE_BALANCER_1 = 0x2000000000000;
    uint256 internal constant FLAG_DISABLE_BALANCER_2 = 0x4000000000000;
    uint256 internal constant FLAG_DISABLE_BALANCER_3 = 0x8000000000000;
    uint256 internal constant DEPRECATED_FLAG_ENABLE_KYBER_UNISWAP_RESERVE = 0x10000000000000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_KYBER_OASIS_RESERVE = 0x20000000000000; // Deprecated, Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_KYBER_BANCOR_RESERVE = 0x40000000000000; // Deprecated, Turned off by default
    uint256 internal constant FLAG_ENABLE_REFERRAL_GAS_SPONSORSHIP = 0x80000000000000; // Turned off by default
    uint256 internal constant DEPRECATED_FLAG_ENABLE_MULTI_PATH_COMP = 0x100000000000000; // Deprecated, Turned off by default
    uint256 internal constant FLAG_DISABLE_KYBER_ALL = 0x200000000000000;
    uint256 internal constant FLAG_DISABLE_KYBER_1 = 0x400000000000000;
    uint256 internal constant FLAG_DISABLE_KYBER_2 = 0x800000000000000;
    uint256 internal constant FLAG_DISABLE_KYBER_3 = 0x1000000000000000;
    uint256 internal constant FLAG_DISABLE_KYBER_4 = 0x2000000000000000;
    uint256 internal constant FLAG_ENABLE_CHI_BURN_BY_ORIGIN = 0x4000000000000000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP_ALL = 0x8000000000000000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP_ETH = 0x10000000000000000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP_DAI = 0x20000000000000000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP_USDC = 0x40000000000000000;
    uint256 internal constant FLAG_DISABLE_MOONISWAP_POOL_TOKEN = 0x80000000000000000;
}


contract IOneSplit is IOneSplitConsts {
    function getExpectedReturn(
        IERC20 fromToken,
        IERC20 destToken,
        uint256 amount,
        uint256 parts,
        uint256 flags // See constants in IOneSplit.sol
    )
        public
        view
        returns(
            uint256 returnAmount,
            uint256[] memory distribution
        );

    function getExpectedReturnWithGas(
        IERC20 fromToken,
        IERC20 destToken,
        uint256 amount,
        uint256 parts,
        uint256 flags, // See constants in IOneSplit.sol
        uint256 destTokenEthPriceTimesGasPrice
    )
        public
        view
        returns(
            uint256 returnAmount,
            uint256 estimateGasAmount,
            uint256[] memory distribution
        );

    function swap(
        IERC20 fromToken,
        IERC20 destToken,
        uint256 amount,
        uint256 minReturn,
        uint256[] memory distribution,
        uint256 flags
    )
        public
        payable
        returns(uint256 returnAmount);
}


contract IOneSplitMulti is IOneSplit {
    function getExpectedReturnWithGasMulti(
        IERC20[] memory tokens,
        uint256 amount,
        uint256[] memory parts,
        uint256[] memory flags,
        uint256[] memory destTokenEthPriceTimesGasPrices
    )
        public
        view
        returns(
            uint256[] memory returnAmounts,
            uint256 estimateGasAmount,
            uint256[] memory distribution
        );

    function swapMulti(
        IERC20[] memory tokens,
        uint256 amount,
        uint256 minReturn,
        uint256[] memory distribution,
        uint256[] memory flags
    )
        public
        payable
        returns(uint256 returnAmount);
}

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: contracts/interface/IUniswapExchange.sol

pragma solidity ^0.5.0;



interface IUniswapExchange {
    function getEthToTokenInputPrice(uint256 ethSold) external view returns (uint256 tokensBought);

    function getTokenToEthInputPrice(uint256 tokensSold) external view returns (uint256 ethBought);

    function ethToTokenSwapInput(uint256 minTokens, uint256 deadline)
        external
        payable
        returns (uint256 tokensBought);

    function tokenToEthSwapInput(uint256 tokensSold, uint256 minEth, uint256 deadline)
        external
        returns (uint256 ethBought);

    function tokenToTokenSwapInput(
        uint256 tokensSold,
        uint256 minTokensBought,
        uint256 minEthBought,
        uint256 deadline,
        address tokenAddr
    ) external returns (uint256 tokensBought);
}

// File: contracts/interface/IUniswapFactory.sol

pragma solidity ^0.5.0;



interface IUniswapFactory {
    function getExchange(IERC20 token) external view returns (IUniswapExchange exchange);
}

// File: contracts/interface/IKyberNetworkContract.sol

pragma solidity ^0.5.0;



interface IKyberNetworkContract {
    function searchBestRate(IERC20 src, IERC20 dest, uint256 srcAmount, bool usePermissionless)
        external
        view
        returns (address reserve, uint256 rate);
}

// File: contracts/interface/IKyberNetworkProxy.sol

pragma solidity ^0.5.0;



interface IKyberNetworkProxy {
    function getExpectedRateAfterFee(
        IERC20 src,
        IERC20 dest,
        uint256 srcQty,
        uint256 platformFeeBps,
        bytes calldata hint
    ) external view returns (uint256 expectedRate);

    function tradeWithHintAndFee(
        IERC20 src,
        uint256 srcAmount,
        IERC20 dest,
        address payable destAddress,
        uint256 maxDestAmount,
        uint256 minConversionRate,
        address payable platformWallet,
        uint256 platformFeeBps,
        bytes calldata hint
    ) external payable returns (uint256 destAmount);

    function kyberNetworkContract() external view returns (IKyberNetworkContract);

    // TODO: Limit usage by tx.gasPrice
    // function maxGasPrice() external view returns (uint256);

    // TODO: Limit usage by user cap
    // function getUserCapInWei(address user) external view returns (uint256);
    // function getUserCapInTokenWei(address user, IERC20 token) external view returns (uint256);
}

// File: contracts/interface/IKyberStorage.sol

pragma solidity ^0.5.0;



interface IKyberStorage {
    function getReserveIdsPerTokenSrc(
        IERC20 token
    ) external view returns (bytes32[] memory);
}

// File: contracts/interface/IKyberHintHandler.sol

pragma solidity ^0.5.0;



interface IKyberHintHandler {
    enum TradeType {
        BestOfAll,
        MaskIn,
        MaskOut,
        Split
    }

    function buildTokenToEthHint(
        IERC20 tokenSrc,
        TradeType tokenToEthType,
        bytes32[] calldata tokenToEthReserveIds,
        uint256[] calldata tokenToEthSplits
    ) external view returns (bytes memory hint);

    function buildEthToTokenHint(
        IERC20 tokenDest,
        TradeType ethToTokenType,
        bytes32[] calldata ethToTokenReserveIds,
        uint256[] calldata ethToTokenSplits
    ) external view returns (bytes memory hint);
}

// File: contracts/interface/IBancorNetwork.sol

pragma solidity ^0.5.0;


interface IBancorNetwork {
    function getReturnByPath(address[] calldata path, uint256 amount)
        external
        view
        returns (uint256 returnAmount, uint256 conversionFee);

    function claimAndConvert(address[] calldata path, uint256 amount, uint256 minReturn)
        external
        returns (uint256);

    function convert(address[] calldata path, uint256 amount, uint256 minReturn)
        external
        payable
        returns (uint256);
}

// File: contracts/interface/IBancorContractRegistry.sol

pragma solidity ^0.5.0;


contract IBancorContractRegistry {
    function addressOf(bytes32 contractName) external view returns (address);
}

// File: contracts/interface/IBancorNetworkPathFinder.sol

pragma solidity ^0.5.0;



interface IBancorNetworkPathFinder {
    function generatePath(IERC20 sourceToken, IERC20 targetToken)
        external
        view
        returns (address[] memory);
}

// File: contracts/interface/IBancorConverterRegistry.sol

pragma solidity ^0.5.0;



interface IBancorConverterRegistry {

    function getConvertibleTokenSmartTokenCount(IERC20 convertibleToken)
        external view returns(uint256);

    function getConvertibleTokenSmartTokens(IERC20 convertibleToken)
        external view returns(address[] memory);

    function getConvertibleTokenSmartToken(IERC20 convertibleToken, uint256 index)
        external view returns(address);

    function isConvertibleTokenSmartToken(IERC20 convertibleToken, address value)
        external view returns(bool);
}

// File: contracts/interface/IBancorEtherToken.sol

pragma solidity ^0.5.0;



contract IBancorEtherToken is IERC20 {
    function deposit() external payable;

    function withdraw(uint256 amount) external;
}

// File: contracts/interface/IBancorFinder.sol

pragma solidity ^0.5.0;



interface IBancorFinder {
    function buildBancorPath(
        IERC20 fromToken,
        IERC20 destToken
    )
        external
        view
        returns(address[] memory path);
}

// File: contracts/interface/IOasisExchange.sol

pragma solidity ^0.5.0;



interface IOasisExchange {
    function getBuyAmount(IERC20 buyGem, IERC20 payGem, uint256 payAmt)
        external
        view
        returns (uint256 fillAmt);

    function sellAllAmount(IERC20 payGem, uint256 payAmt, IERC20 buyGem, uint256 minFillAmount)
        external
        returns (uint256 fillAmt);
}

// File: contracts/interface/IWETH.sol

pragma solidity ^0.5.0;



contract IWETH is IERC20 {
    function deposit() external payable;

    function withdraw(uint256 amount) external;
}

// File: contracts/interface/ICurve.sol

pragma solidity ^0.5.0;


interface ICurve {
    // solium-disable-next-line mixedcase
    function get_dy_underlying(int128 i, int128 j, uint256 dx) external view returns(uint256 dy);

    // solium-disable-next-line mixedcase
    function get_dy(int128 i, int128 j, uint256 dx) external view returns(uint256 dy);

    // solium-disable-next-line mixedcase
    function exchange_underlying(int128 i, int128 j, uint256 dx, uint256 minDy) external;

    // solium-disable-next-line mixedcase
    function exchange(int128 i, int128 j, uint256 dx, uint256 minDy) external;
}


contract ICurveRegistry {
    function get_pool_info(address pool)
        external
        view
        returns(
            uint256[8] memory balances,
            uint256[8] memory underlying_balances,
            uint256[8] memory decimals,
            uint256[8] memory underlying_decimals,
            address lp_token,
            uint256 A,
            uint256 fee
        );
}


contract ICurveCalculator {
    function get_dy(
        int128 nCoins,
        uint256[8] calldata balances,
        uint256 amp,
        uint256 fee,
        uint256[8] calldata rates,
        uint256[8] calldata precisions,
        bool underlying,
        int128 i,
        int128 j,
        uint256[100] calldata dx
    ) external view returns(uint256[100] memory dy);
}

// File: contracts/interface/IChai.sol

pragma solidity ^0.5.0;



interface IPot {
    function dsr() external view returns (uint256);

    function chi() external view returns (uint256);

    function rho() external view returns (uint256);

    function drip() external returns (uint256);

    function join(uint256) external;

    function exit(uint256) external;
}


contract IChai is IERC20 {
    function POT() public view returns (IPot);

    function join(address dst, uint256 wad) external;

    function exit(address src, uint256 wad) external;
}


library ChaiHelper {
    IPot private constant POT = IPot(0x197E90f9FAD81970bA7976f33CbD77088E5D7cf7);
    uint256 private constant RAY = 10**27;

    function _mul(uint256 x, uint256 y) private pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x);
    }

    function _rmul(uint256 x, uint256 y) private pure returns (uint256 z) {
        // always rounds down
        z = _mul(x, y) / RAY;
    }

    function _rdiv(uint256 x, uint256 y) private pure returns (uint256 z) {
        // always rounds down
        z = _mul(x, RAY) / y;
    }

    function rpow(uint256 x, uint256 n, uint256 base) private pure returns (uint256 z) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            switch x
                case 0 {
                    switch n
                        case 0 {
                            z := base
                        }
                        default {
                            z := 0
                        }
                }
                default {
                    switch mod(n, 2)
                        case 0 {
                            z := base
                        }
                        default {
                            z := x
                        }
                    let half := div(base, 2) // for rounding.
                    for {
                        n := div(n, 2)
                    } n {
                        n := div(n, 2)
                    } {
                        let xx := mul(x, x)
                        if iszero(eq(div(xx, x), x)) {
                            revert(0, 0)
                        }
                        let xxRound := add(xx, half)
                        if lt(xxRound, xx) {
                            revert(0, 0)
                        }
                        x := div(xxRound, base)
                        if mod(n, 2) {
                            let zx := mul(z, x)
                            if and(iszero(iszero(x)), iszero(eq(div(zx, x), z))) {
                                revert(0, 0)
                            }
                            let zxRound := add(zx, half)
                            if lt(zxRound, zx) {
                                revert(0, 0)
                            }
                            z := div(zxRound, base)
                        }
                    }
                }
        }
    }

    function potDrip() private view returns (uint256) {
        return _rmul(rpow(POT.dsr(), now - POT.rho(), RAY), POT.chi());
    }

    function chaiPrice(IChai chai) internal view returns(uint256) {
        return chaiToDai(chai, 1e18);
    }

    function daiToChai(
        IChai /*chai*/,
        uint256 amount
    ) internal view returns (uint256) {
        uint256 chi = (now > POT.rho()) ? potDrip() : POT.chi();
        return _rdiv(amount, chi);
    }

    function chaiToDai(
        IChai /*chai*/,
        uint256 amount
    ) internal view returns (uint256) {
        uint256 chi = (now > POT.rho()) ? potDrip() : POT.chi();
        return _rmul(chi, amount);
    }
}

// File: contracts/interface/ICompound.sol

pragma solidity ^0.5.0;



contract ICompound {
    function markets(address cToken)
        external
        view
        returns (bool isListed, uint256 collateralFactorMantissa);
}


contract ICompoundToken is IERC20 {
    function underlying() external view returns (address);

    function exchangeRateStored() external view returns (uint256);

    function mint(uint256 mintAmount) external returns (uint256);

    function redeem(uint256 redeemTokens) external returns (uint256);
}


contract ICompoundEther is IERC20 {
    function mint() external payable;

    function redeem(uint256 redeemTokens) external returns (uint256);
}

// File: contracts/interface/ICompoundRegistry.sol

pragma solidity ^0.5.0;




contract ICompoundRegistry {
    function tokenByCToken(ICompoundToken cToken) external view returns(IERC20);
    function cTokenByToken(IERC20 token) external view returns(ICompoundToken);
}

// File: contracts/interface/IAaveToken.sol

pragma solidity ^0.5.0;



contract IAaveToken is IERC20 {
    function underlyingAssetAddress() external view returns (IERC20);

    function redeem(uint256 amount) external;
}


interface IAaveLendingPool {
    function core() external view returns (address);

    function deposit(IERC20 token, uint256 amount, uint16 refCode) external payable;
}

// File: contracts/interface/IAaveRegistry.sol

pragma solidity ^0.5.0;




contract IAaveRegistry {
    function tokenByAToken(IAaveToken aToken) external view returns(IERC20);
    function aTokenByToken(IERC20 token) external view returns(IAaveToken);
}

// File: contracts/interface/IMooniswap.sol

pragma solidity ^0.5.0;



interface IMooniswapRegistry {
    function pools(IERC20 token1, IERC20 token2) external view returns(IMooniswap);
    function isPool(address addr) external view returns(bool);
}


interface IMooniswap {
    function fee() external view returns (uint256);

    function tokens(uint256 i) external view returns (IERC20);

    function deposit(uint256[] calldata amounts, uint256[] calldata minAmounts) external payable returns(uint256 fairSupply);

    function withdraw(uint256 amount, uint256[] calldata minReturns) external;

    function getBalanceForAddition(IERC20 token) external view returns(uint256);

    function getBalanceForRemoval(IERC20 token) external view returns(uint256);

    function getReturn(
        IERC20 fromToken,
        IERC20 destToken,
        uint256 amount
    )
        external
        view
        returns(uint256 returnAmount);

    function swap(
        IERC20 fromToken,
        IERC20 destToken,
        uint256 amount,
        uint256 minReturn,
        address referral
    )
        external
        payable
        returns(uint256 returnAmount);
}

// File: @openzeppelin/contracts/math/Math.sol

pragma solidity ^0.5.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol

pragma solidity ^0.5.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != accountHash && codehash != 0x0);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-call-value
        (bool success, ) = recipient.call.value(amount)("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }
}

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

pragma solidity ^0.5.0;




/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: contracts/UniversalERC20.sol

pragma solidity ^0.5.0;





library UniversalERC20 {

    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000);
    IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    function universalTransfer(IERC20 token, address to, uint256 amount) internal returns(bool) {
        if (amount == 0) {
            return true;
        }

        if (isETH(token)) {
            address(uint160(to)).transfer(amount);
        } else {
            token.safeTransfer(to, amount);
            return true;
        }
    }

    function universalTransferFrom(IERC20 token, address from, address to, uint256 amount) internal {
        if (amount == 0) {
            return;
        }

        if (isETH(token)) {
            require(from == msg.sender && msg.value >= amount, "Wrong useage of ETH.universalTransferFrom()");
            if (to != address(this)) {
                address(uint160(to)).transfer(amount);
            }
            if (msg.value > amount) {
                msg.sender.transfer(msg.value.sub(amount));
            }
        } else {
            token.safeTransferFrom(from, to, amount);
        }
    }

    function universalTransferFromSenderToThis(IERC20 token, uint256 amount) internal {
        if (amount == 0) {
            return;
        }

        if (isETH(token)) {
            if (msg.value > amount) {
                // Return remainder if exist
                msg.sender.transfer(msg.value.sub(amount));
            }
        } else {
            token.safeTransferFrom(msg.sender, address(this), amount);
        }
    }

    function universalApprove(IERC20 token, address to, uint256 amount) internal {
        if (!isETH(token)) {
            if (amount == 0) {
                token.safeApprove(to, 0);
                return;
            }

            uint256 allowance = token.allowance(address(this), to);
            if (allowance < amount) {
                if (allowance > 0) {
                    token.safeApprove(to, 0);
                }
                token.safeApprove(to, amount);
            }
        }
    }

    function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) {
        if (isETH(token)) {
            return who.balance;
        } else {
            return token.balanceOf(who);
        }
    }

    function universalDecimals(IERC20 token) internal view returns (uint256) {

        if (isETH(token)) {
            return 18;
        }

        (bool success, bytes memory data) = address(token).staticcall.gas(10000)(
            abi.encodeWithSignature("decimals()")
        );
        if (!success || data.length == 0) {
            (success, data) = address(token).staticcall.gas(10000)(
                abi.encodeWithSignature("DECIMALS()")
            );
        }

        return (success && data.length > 0) ? abi.decode(data, (uint256)) : 18;
    }

    function isETH(IERC20 token) internal pure returns(bool) {
        return (address(token) == address(ZERO_ADDRESS) || address(token) == address(ETH_ADDRESS));
    }

    function eq(IERC20 a, IERC20 b) internal pure returns(bool) {
        return a == b || (isETH(a) && isETH(b));
    }

    function notExist(IERC20 token) internal pure returns(bool) {
        return (address(token) == address(-1));
    }
}

// File: contracts/interface/IUniswapV2Exchange.sol

pragma solidity ^0.5.0;






interface IUniswapV2Exchange {
    function getReserves() external view returns(uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;
}


library UniswapV2ExchangeLib {
    using Math for uint256;
    using SafeMath for uint256;
    using UniversalERC20 for IERC20;

    function getReturn(
        IUniswapV2Exchange exchange,
        IERC20 fromToken,
        IERC20 destToken,
        uint amountIn
    ) internal view returns (uint256 result, bool needSync, bool needSkim) {
        uint256 reserveIn = fromToken.universalBalanceOf(address(exchange));
        uint256 reserveOut = destToken.universalBalanceOf(address(exchange));
        (uint112 reserve0, uint112 reserve1,) = exchange.getReserves();
        if (fromToken > destToken) {
            (reserve0, reserve1) = (reserve1, reserve0);
        }
        needSync = (reserveIn < reserve0 || reserveOut < reserve1);
        needSkim = !needSync && (reserveIn > reserve0 || reserveOut > reserve1);

        uint256 amountInWithFee = amountIn.mul(997);
        uint256 numerator = amountInWithFee.mul(Math.min(reserveOut, reserve1));
        uint256 denominator = Math.min(reserveIn, reserve0).mul(1000).add(amountInWithFee);
        result = (denominator == 0) ? 0 : numerator.div(denominator);
    }
}

// File: contracts/interface/IUniswapV2Factory.sol

pragma solidity ^0.5.0;



interface IUniswapV2Factory {
    function getPair(IERC20 tokenA, IERC20 tokenB) external view returns (IUniswapV2Exchange pair);
}

// File: contracts/interface/IDForceSwap.sol

pragma solidity ^0.5.0;



interface IDForceSwap {
    function getAmountByInput(IERC20 input, IERC20 output, uint256 amount) external view returns(uint256);
    function swap(IERC20 input, IERC20 output, uint256 amount) external;
}

// File: contracts/interface/IShell.sol

pragma solidity ^0.5.0;


interface IShell {
    function viewOriginTrade(
        address origin,
        address target,
        uint256 originAmount
    ) external view returns (uint256);

    function swapByOrigin(
        address origin,
        address target,
        uint256 originAmount,
        uint256 minTargetAmount,
        uint256 deadline
    ) external returns (uint256);
}

// File: contracts/interface/IMStable.sol

pragma solidity ^0.5.0;



contract IMStable is IERC20 {
    function getSwapOutput(
        IERC20 _input,
        IERC20 _output,
        uint256 _quantity
    )
        external
        view
        returns (bool, string memory, uint256 output);

    function swap(
        IERC20 _input,
        IERC20 _output,
        uint256 _quantity,
        address _recipient
    )
        external
        returns (uint256 output);

    function redeem(
        IERC20 _basset,
        uint256 _bassetQuantity
    )
        external
        returns (uint256 massetRedeemed);
}

interface IMassetValidationHelper {
    /**
     * @dev Returns a valid bAsset to redeem
     * @param _mAsset Masset addr
     * @return valid bool
     * @return string message
     * @return address of bAsset to redeem
     */
    function suggestRedeemAsset(
        IERC20 _mAsset
    )
        external
        view
        returns (
            bool valid,
            string memory err,
            address token
        );

    /**
     * @dev Returns a valid bAsset with which to mint
     * @param _mAsset Masset addr
     * @return valid bool
     * @return string message
     * @return address of bAsset to mint
     */
    function suggestMintAsset(
        IERC20 _mAsset
    )
        external
        view
        returns (
            bool valid,
            string memory err,
            address token
        );

    /**
     * @dev Determines if a given Redemption is valid
     * @param _mAsset Address of the given mAsset (e.g. mUSD)
     * @param _mAssetQuantity Amount of mAsset to redeem (in mUSD units)
     * @param _outputBasset Desired output bAsset
     * @return valid
     * @return validity reason
     * @return output in bAsset units
     * @return bAssetQuantityArg - required input argument to the 'redeem' call
     */
    function getRedeemValidity(
        IERC20 _mAsset,
        uint256 _mAssetQuantity,
        IERC20 _outputBasset
    )
        external
        view
        returns (
            bool valid,
            string memory,
            uint256 output,
            uint256 bassetQuantityArg
        );
}

// File: contracts/interface/IBalancerPool.sol

pragma solidity ^0.5.0;



interface IBalancerPool {
    function getSwapFee()
        external view returns (uint256 balance);

    function getDenormalizedWeight(IERC20 token)
        external view returns (uint256 balance);

    function getBalance(IERC20 token)
        external view returns (uint256 balance);

    function swapExactAmountIn(
        IERC20 tokenIn,
        uint256 tokenAmountIn,
        IERC20 tokenOut,
        uint256 minAmountOut,
        uint256 maxPrice
    )
        external
        returns (uint256 tokenAmountOut, uint256 spotPriceAfter);
}


// 0xA961672E8Db773be387e775bc4937C678F3ddF9a
interface IBalancerHelper {
    function getReturns(
        IBalancerPool pool,
        IERC20 fromToken,
        IERC20 destToken,
        uint256[] calldata amounts
    )
        external
        view
        returns(uint256[] memory rets);
}

// File: contracts/interface/IBalancerRegistry.sol

pragma solidity ^0.5.0;




interface IBalancerRegistry {
    event PoolAdded(
        address indexed pool
    );
    event PoolTokenPairAdded(
        address indexed pool,
        address indexed fromToken,
        address indexed destToken
    );
    event IndicesUpdated(
        address indexed fromToken,
        address indexed destToken,
        bytes32 oldIndices,
        bytes32 newIndices
    );

    // Get info about pool pair for 1 SLOAD
    function getPairInfo(address pool, address fromToken, address destToken)
        external view returns(uint256 weight1, uint256 weight2, uint256 swapFee);

    // Pools
    function checkAddedPools(address pool)
        external view returns(bool);
    function getAddedPoolsLength()
        external view returns(uint256);
    function getAddedPools()
        external view returns(address[] memory);
    function getAddedPoolsWithLimit(uint256 offset, uint256 limit)
        external view returns(address[] memory result);

    // Tokens
    function getAllTokensLength()
        external view returns(uint256);
    function getAllTokens()
        external view returns(address[] memory);
    function getAllTokensWithLimit(uint256 offset, uint256 limit)
        externa...

// [truncated — 231808 bytes total]

Read Contract

getExpectedReturn 0x085e2c5b → uint256, uint256[]
getExpectedReturnWithGas 0x8373f265 → uint256, uint256, uint256[]
oneSplitView 0xfbe4ed95 → address

Write Contract 1 functions

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

swap 0xe2a7515e
address fromToken
address destToken
uint256 amount
uint256 minReturn
uint256[] distribution
uint256 flags
returns: uint256

Top Interactions

AddressTxnsSentReceived
0x083fc10c...4E45 1 1

Recent Transactions

CSV
|
Hash Method Block Age From/To Value Txn Fee Type
0x2f70c5bd...c6aa28 0x60806040 10,634,749 IN 0x083fc10c...4E45 0 ETH 0.41494311 ETH Legacy