Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0x11bafFebd829B490Cf077Ce7eF7700dd3cB1e534
Balance 0 ETH
Nonce 1
Code Size 12888 bytes
Indexed Transactions 0 (1 on-chain, <1% indexed)
External Etherscan · Sourcify

Contract Bytecode

12888 bytes
Copy Bytecode
0x608060405234801561001057600080fd5b50600436106101cf5760003560e01c806370a0823111610104578063bb7e8c28116100a2578063dd62ed3e11610071578063dd62ed3e14610579578063ddca3f43146105a7578063e1c3d3a4146105af578063f5f5de05146105d8576101cf565b8063bb7e8c281461051d578063bf1ab21414610525578063c0324c771461054e578063cb4a785e14610571576101cf565b806395d89b41116100de57806395d89b41146104ac5780639eb120c0146104b4578063a9059cbb146104e9578063b0e21e8a14610515576101cf565b806370a082311461040a578063909003561461043057806394edaa6314610459576101cf565b80633cfd1ccc11610171578063671d1c061161014b578063671d1c06146103615780636817031b146103695780636adadd3514610391578063704b6c02146103e4576101cf565b80633cfd1ccc146103305780634be1c796146103515780635ddc916a14610359576101cf565b806323b872dd116101ad57806323b872dd146102ab57806326882737146102e15780632c4e722e1461030a578063313ce56714610312576101cf565b806306fdde03146101d4578063095ea7b31461025157806318160ddd14610291575b600080fd5b6101dc61060d565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102165781810151838201526020016101fe565b50505050905090810190601f1680156102435780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61027d6004803603604081101561026757600080fd5b506001600160a01b03813516906020013561069b565b604080519115158252519081900360200190f35b610299610702565b60408051918252519081900360200190f35b61027d600480360360608110156102c157600080fd5b506001600160a01b03813581169160208101359091169060400135610708565b610299600480360360608110156102f757600080fd5b5080359060208101359060400135610775565b610299610953565b61031a61095c565b6040805160ff9092168252519081900360200190f35b610338610965565b6040805192835260208301919091528051918290030190f35b610299610af2565b610338610b3e565b610299610d0f565b61038f6004803603602081101561037f57600080fd5b50356001600160a01b0316610d1b565b005b610338600480360360608110156103a757600080fd5b604080518082018252833593928301929160608301919060208401906002908390839080828437600092019190915250919450610d549350505050565b61038f600480360360208110156103fa57600080fd5b50356001600160a01b03166112ad565b6102996004803603602081101561042057600080fd5b50356001600160a01b03166112e6565b6102996004803603606081101561044657600080fd5b5080359060208101359060400135611301565b6103386004803603606081101561046f57600080fd5b6040805180820182528335939283019291606083019190602084019060029083908390808284376000920191909152509194506114a99350505050565b6101dc6118c4565b610299600480360360a08110156104ca57600080fd5b508035906020810135906040810135906060810135906080013561191f565b61027d600480360360408110156104ff57600080fd5b506001600160a01b038135169060200135611989565b61029961199f565b6101dc6119a5565b6102996004803603606081101561053b57600080fd5b5080359060208101359060400135611a00565b61038f6004803603604081101561056457600080fd5b5080359060200135611baa565b61038f611c23565b6102996004803603604081101561058f57600080fd5b506001600160a01b0381358116916020013516612159565b610299612184565b610299600480360360608110156105c557600080fd5b508035906020810135906040013561218a565b610299600480360360a08110156105ee57600080fd5b5080359060208101359060408101359060608101359060800135612339565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106935780601f1061066857610100808354040283529160200191610693565b820191906000526020600020905b81548152906001019060200180831161067657829003601f168201915b505050505081565b3360008181526001602090815260408083206001600160a01b038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b60025490565b6001600160a01b038316600090815260016020908152604080832033845290915281205461073c908363ffffffff61239516565b6001600160a01b038516600090815260016020908152604080832033845290915290205561076b8484846123aa565b5060019392505050565b6000814211156107b6576040805162461bcd60e51b81526020600482015260076024820152661156141254915160ca1b604482015290519081900360640190fd5b6000806107c1610b3e565b915091506000806107d0610965565b91509150600061082661081d6107e4610953565b610811670de0b6b3a76400006108056007548f61247590919063ffffffff16565b9063ffffffff6124a316565b9063ffffffff61247516565b8484888861191f565b90506108368982858589896124c5565b8781101561087f576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b6108a361089a61088d610953565b8b9063ffffffff61247516565b86868686612558565b6108e36000805160206131e48339815191526000805160206132048339815191526108dc6108cf610953565b869063ffffffff6124a316565b338d6125c2565b61090c6000805160206131c48339815191526000805160206131a4833981519152873385612968565b604080518a81526020810183905281516000805160206131c4833981519152923392600080516020613184833981519152929081900390910190a398975050505050505050565b64e8d4a5100090565b60055460ff1681565b604080516370a0823160e01b815230600482015290516000918291600a91600080516020613204833981519152916370a0823191602480820192602092909190829003018186803b1580156109b957600080fd5b505afa1580156109cd573d6000803e3d6000fd5b505050506040513d60208110156109e357600080fd5b505111610a86576000610a7c6109f7610953565b604080516305eff7ef60e21b81523060048201529051600080516020613204833981519152916317bfdfbc9160248083019260209291908290030181600087803b158015610a4457600080fd5b505af1158015610a58573d6000803e3d6000fd5b505050506040513d6020811015610a6e57600080fd5b50519063ffffffff61247516565b9092509050610aee565b610ade610a91610953565b60408051633af9e66960e01b8152306004820152905160008051602061320483398151915291633af9e6699160248083019260209291908290030181600087803b158015610a4457600080fd5b610ae96109f7610953565b915091505b9091565b6000806000610aff610b3e565b91509150600080610b0e610965565b9092509050610b3581610b298581888763ffffffff612d1b16565b9063ffffffff61239516565b94505050505090565b604080516370a0823160e01b815230600482015290516000918291600a916000805160206131a4833981519152916370a0823191602480820192602092909190829003018186803b158015610b9257600080fd5b505afa158015610ba6573d6000803e3d6000fd5b505050506040513d6020811015610bbc57600080fd5b505111610c4957604080516305eff7ef60e21b815230600482015290516000916000805160206131a4833981519152916317bfdfbc9160248082019260209290919082900301818787803b158015610c1357600080fd5b505af1158015610c27573d6000803e3d6000fd5b505050506040513d6020811015610c3d57600080fd5b50519092509050610aee565b60408051633af9e66960e01b815230600482015290516000805160206131a483398151915291633af9e6699160248083019260209291908290030181600087803b158015610c9657600080fd5b505af1158015610caa573d6000803e3d6000fd5b505050506040513d6020811015610cc057600080fd5b5051604080516305eff7ef60e21b815230600482015290516000805160206131a4833981519152916317bfdfbc9160248083019260209291908290030181600087803b158015610c1357600080fd5b670a688906bd8b000081565b6009546001600160a01b03163314610d3257600080fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b60008066038d7ea4c68000841015610da6576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d05491d55351539560821b604482015290519081900360640190fd5b610dae611c23565b600254156111df57600080610dc1610b3e565b91509150600080610dd0610965565b9150915082841015610f71576000610dee848663ffffffff61239516565b90506000610e02848463ffffffff61239516565b90506000610e1f600254610805858e61247590919063ffffffff16565b90506000610e3c600254610805858f61247590919063ffffffff16565b9050610e56610e49610953565b829063ffffffff6124a316565b8b519091508210801590610e6e575060208b01518111155b610eb3576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b610ebd338d612d2d565b610efd6000805160206131e4833981519152600080516020613204833981519152610ef6610ee9610953565b899063ffffffff6124a316565b33856125c2565b610f266000805160206131c48339815191526000805160206131a48339815191528a3386612968565b6040805183815260208101839052815133927f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca928290030190a290985096506112a695505050505050565b808210156110b6576000610f8b858563ffffffff61239516565b90506000610f9f838563ffffffff61239516565b90506000610fbc600254610805858e61247590919063ffffffff16565b90506000610fd9600254610805858f61247590919063ffffffff16565b9050610fe6610e49610953565b8b519091508211801590610ffe575060208b01518110155b611043576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b61104d338d612d2d565b6110766000805160206131c48339815191526000805160206131a48339815191528933866125c2565b610f266000805160206131e48339815191526000805160206132048339815191526110af6110a2610953565b8a9063ffffffff6124a316565b3385612968565b60006110c8858563ffffffff61239516565b905060006110dc848463ffffffff61239516565b905060006110f9600254610805858e61247590919063ffffffff16565b90506000611116600254610805858f61247590919063ffffffff16565b9050611123610e49610953565b8b51909150821180159061113b575060208b01518111155b611180576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b61118a338d612d2d565b6111b36000805160206131c48339815191526000805160206131a48339815191528933866125c2565b610f266000805160206131e4833981519152600080516020613204833981519152610ef6610ee9610953565b60006111f285600263ffffffff6124a316565b905060006112066002610805610ee9610953565b90506112123387612d2d565b61123c6000805160206131c48339815191526000805160206131a4833981519152600033866125c2565b6112666000805160206131e4833981519152600080516020613204833981519152600033856125c2565b6040805183815260208101839052815133927f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca928290030190a290925090505b9250929050565b6009546001600160a01b031633146112c457600080fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b031660009081526020819052604090205490565b600081421115611342576040805162461bcd60e51b81526020600482015260076024820152661156141254915160ca1b604482015290519081900360640190fd5b60008061134d610b3e565b9150915060008061135c610965565b91509150600061136f8884848888612339565b905061137f8189858589896124c5565b6113a761138a610953565b600754610805908185670de0b6b3a764000063ffffffff61247516565b9050888111156113f2576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b61140d61089a611400610953565b839063ffffffff61247516565b6114396000805160206131e4833981519152600080516020613204833981519152610ef66108cf610953565b6114626000805160206131c48339815191526000805160206131a483398151915287338c612968565b60408051828152602081018a905281516000805160206131c4833981519152923392600080516020613184833981519152929081900390910190a398975050505050505050565b600080600084116114f4576040805162461bcd60e51b815260206004820152601060248201526f1253959053125117d05491d55351539560821b604482015290519081900360640190fd5b6114fc611c23565b600080611507610b3e565b91509150600080611516610965565b9150915082841015611696576000611534848663ffffffff61239516565b90506000611548848463ffffffff61239516565b90506000611565600254610805858e61247590919063ffffffff16565b90506000611582600254610805858f61247590919063ffffffff16565b905061158f610e49610953565b8b5190915082118015906115a7575060208b01518110155b6115ec576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b6115f6338d612e19565b61161f6000805160206131c48339815191526000805160206131a48339815191528933866125c2565b61164b6000805160206131e48339815191526000805160206132048339815191526110af6110a2610953565b6040805183815260208101839052815133927f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e8928290030190a290985096506112a695505050505050565b808210156117c75760006116b0858563ffffffff61239516565b905060006116c4838563ffffffff61239516565b905060006116e1600254610805858e61247590919063ffffffff16565b905060006116fe600254610805858f61247590919063ffffffff16565b905061170b610e49610953565b8b519091508210801590611723575060208b01518111155b611768576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b611772338d612e19565b61179e6000805160206131e4833981519152600080516020613204833981519152610ef6610ee9610953565b61164b6000805160206131c48339815191526000805160206131a48339815191528a3386612968565b60006117d9858563ffffffff61239516565b905060006117ed848463ffffffff61239516565b9050600061180a600254610805858e61247590919063ffffffff16565b90506000611827600254610805858f61247590919063ffffffff16565b9050611834610e49610953565b8b51909150821080159061184c575060208b01518110155b611891576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b61189b338d612e19565b61161f6000805160206131c48339815191526000805160206131a48339815191528a3386612968565b6004805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106935780601f1061066857610100808354040283529160200191610693565b600080611932868663ffffffff612eb616565b90506000611946858563ffffffff612eb616565b9050600061195a838a63ffffffff612ee916565b90506000611969828585612f1b565b905061197b838263ffffffff612eb616565b9a9950505050505050505050565b60006119963384846123aa565b50600192915050565b60085481565b6006805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106935780601f1061066857610100808354040283529160200191610693565b600081421115611a41576040805162461bcd60e51b81526020600482015260076024820152661156141254915160ca1b604482015290519081900360640190fd5b600080611a4c610b3e565b91509150600080611a5b610965565b915091506000611a8e611a85670de0b6b3a76400006108056007548d61247590919063ffffffff16565b8686868661191f565b9050611a9e8982878787876124c5565b611aa9610e49610953565b905087811015611af4576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b611b018986868686612558565b611b2a6000805160206131c48339815191526000805160206131a483398151915286338d6125c2565b611b636000805160206131e48339815191526000805160206132048339815191526110af611b56610953565b879063ffffffff6124a316565b604080518a81526020810183905281516000805160206131e4833981519152923392600080516020613184833981519152929081900390910190a398975050505050505050565b6009546001600160a01b03163314611bc157600080fd5b670de0b6b3a764000082108015611be05750670dbd2fc137a300008210155b611be957600080fd5b8015611c18576003611c0d82610805670de0b6b3a76400008663ffffffff61239516565b1015611c1857600080fd5b600791909155600855565b604080516370a0823160e01b8152306004820152905160009173c00e94cb662c3520282e6f5717214004a7f26888916370a0823191602480820192602092909190829003018186803b158015611c7857600080fd5b505afa158015611c8c573d6000803e3d6000fd5b505050506040513d6020811015611ca257600080fd5b5051905080611cb15750612157565b600080611cbc610b3e565b91509150600080611ccb610965565b90925090506000611ce2838563ffffffff612d1b16565b611cf2868463ffffffff612d1b16565b604080516003808252608082019092529290911192506060919060208201838038833901905050905073c00e94cb662c3520282e6f5717214004a7f2688881600081518110611d3d57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110611d7f57fe5b60200260200101906001600160a01b031690816001600160a01b03168152505081611db8576000805160206131e4833981519152611dc8565b6000805160206131c48339815191525b81600281518110611dd557fe5b60200260200101906001600160a01b031690816001600160a01b0316815250506060737a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03166338ed17398960008530426040518663ffffffff1660e01b81526004018086815260200185815260200180602001846001600160a01b03166001600160a01b03168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015611e99578181015183820152602001611e81565b505050509050019650505050505050600060405180830381600087803b158015611ec257600080fd5b505af1158015611ed6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611eff57600080fd5b8101908080516040519392919084640100000000821115611f1f57600080fd5b908301906020820185811115611f3457600080fd5b8251866020820283011164010000000082111715611f5157600080fd5b82525081516020918201928201910280838360005b83811015611f7e578181015183820152602001611f66565b5050505090500160405250505090508215612073576000805160206131a48339815191526001600160a01b031663a0712d6882600281518110611fbd57fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015611ffb57600080fd5b505af115801561200f573d6000803e3d6000fd5b505050506040513d602081101561202557600080fd5b50511561206e576040805162461bcd60e51b815260206004820152601260248201527118dd1bdad95b8b9b5a5b9d0819985a5b195960721b604482015290519081900360640190fd5b61214e565b6000805160206132048339815191526001600160a01b031663a0712d688260028151811061209d57fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156120db57600080fd5b505af11580156120ef573d6000803e3d6000fd5b505050506040513d602081101561210557600080fd5b50511561214e576040805162461bcd60e51b815260206004820152601260248201527118dd1bdad95b8b9b5a5b9d0819985a5b195960721b604482015290519081900360640190fd5b50505050505050505b565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60075481565b6000814211156121cb576040805162461bcd60e51b81526020600482015260076024820152661156141254915160ca1b604482015290519081900360640190fd5b6000806121d6610b3e565b915091506000806121e5610965565b91509150600061220f6122066121f9610953565b8a9063ffffffff61247516565b86868686612339565b905061221f8189878787876124c5565b60075461223e9061080583670de0b6b3a764000063ffffffff61247516565b905088811115612289576040805162461bcd60e51b815260206004820152601160248201527014d31254141051d157d111551150d51151607a1b604482015290519081900360640190fd5b6122968186868686612558565b6122bf6000805160206131c48339815191526000805160206131a48339815191528633856125c2565b6122f26000805160206131e48339815191526000805160206132048339815191526122eb611b56610953565b338c612968565b60408051828152602081018a905281516000805160206131e4833981519152923392600080516020613184833981519152929081900390910190a398975050505050505050565b60008061234c868663ffffffff612eb616565b90506000612360858563ffffffff612eb616565b90506000612374828a63ffffffff612eb616565b90506000612383828486612f1b565b905061197b818563ffffffff612eb616565b6000828211156123a457600080fd5b50900390565b6001600160a01b0382166123bd57600080fd5b6001600160a01b0383166000908152602081905260409020546123e6908263ffffffff61239516565b6001600160a01b03808516600090815260208190526040808220939093559084168152205461241b908263ffffffff612d1b16565b6001600160a01b038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600082612484575060006106fc565b8282028284828161249157fe5b041461249c57600080fd5b9392505050565b60008082116124b157600080fd5b60008284816124bc57fe5b04949350505050565b6124d5858263ffffffff612d1b16565b821015612550576124f5603e61081185610b298a8963ffffffff612d1b16565b61250e606461081185610b298a8763ffffffff612d1b16565b10612550576040805162461bcd60e51b815260206004820152600d60248201526c0888a84a8bea89e9ebe9aaa869609b1b604482015290519081900360640190fd5b505050505050565b600854156125bb5760006125a261257b83610b2987818a8963ffffffff612d1b16565b610805600254610811670de0b6b3a76400006108056008548d61247590919063ffffffff16565b600a54909150612550906001600160a01b031682612d2d565b5050505050565b604080516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018490529151918716916323b872dd916064808201926020929091908290030181600087803b15801561261b57600080fd5b505af115801561262f573d6000803e3d6000fd5b505050506040513d602081101561264557600080fd5b505161265057600080fd5b82156128af5780831061272257836001600160a01b0316630e752702826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156126a357600080fd5b505af11580156126b7573d6000803e3d6000fd5b505050506040513d60208110156126cd57600080fd5b50511561271d576040805162461bcd60e51b815260206004820152601960248201527818dd1bdad95b8b9c995c185e509bdc9c9bddc819985a5b1959603a1b604482015290519081900360640190fd5b6128aa565b836001600160a01b0316630e752702846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561276857600080fd5b505af115801561277c573d6000803e3d6000fd5b505050506040513d602081101561279257600080fd5b5051156127e2576040805162461bcd60e51b815260206004820152601960248201527818dd1bdad95b8b9c995c185e509bdc9c9bddc819985a5b1959603a1b604482015290519081900360640190fd5b6001600160a01b03841663a0712d68612801838663ffffffff61239516565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561283757600080fd5b505af115801561284b573d6000803e3d6000fd5b505050506040513d602081101561286157600080fd5b5051156128aa576040805162461bcd60e51b815260206004820152601260248201527118dd1bdad95b8b9b5a5b9d0819985a5b195960721b604482015290519081900360640190fd5b6125bb565b836001600160a01b031663a0712d68826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156128f557600080fd5b505af1158015612909573d6000803e3d6000fd5b505050506040513d602081101561291f57600080fd5b5051156125bb576040805162461bcd60e51b815260206004820152601260248201527118dd1bdad95b8b9b5a5b9d0819985a5b195960721b604482015290519081900360640190fd5b808310612a3857836001600160a01b031663852a12e3826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b1580156129b557600080fd5b505af11580156129c9573d6000803e3d6000fd5b505050506040513d60208110156129df57600080fd5b505115612a33576040805162461bcd60e51b815260206004820152601e60248201527f63746f6b656e2e72656465656d556e6465726c79696e67206661696c65640000604482015290519081900360640190fd5b612c86565b82612af857836001600160a01b031663c5ebeaec826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612a8357600080fd5b505af1158015612a97573d6000803e3d6000fd5b505050506040513d6020811015612aad57600080fd5b505115612a33576040805162461bcd60e51b815260206004820152601460248201527318dd1bdad95b8b989bdc9c9bddc819985a5b195960621b604482015290519081900360640190fd5b836001600160a01b031663852a12e3846040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612b3e57600080fd5b505af1158015612b52573d6000803e3d6000fd5b505050506040513d6020811015612b6857600080fd5b505115612bbc576040805162461bcd60e51b815260206004820152601e60248201527f63746f6b656e2e72656465656d556e6465726c79696e67206661696c65640000604482015290519081900360640190fd5b6001600160a01b03841663c5ebeaec612bdb838663ffffffff61239516565b6040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015612c1157600080fd5b505af1158015612c25573d6000803e3d6000fd5b505050506040513d6020811015612c3b57600080fd5b505115612c86576040805162461bcd60e51b815260206004820152601460248201527318dd1bdad95b8b989bdc9c9bddc819985a5b195960621b604482015290519081900360640190fd5b846001600160a01b031663a9059cbb83836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612ce657600080fd5b505af1158015612cfa573d6000803e3d6000fd5b505050506040513d6020811015612d1057600080fd5b50516125bb57600080fd5b60008282018381101561249c57600080fd5b6001600160a01b038216600090815260208190526040902054612d56908263ffffffff612d1b16565b6001600160a01b038316600090815260208190526040902055600254612d82908263ffffffff612d1b16565b600281905569021e19e0c9bab24000001015612dd4576040805162461bcd60e51b815260206004820152600c60248201526b1c1bdbdb081a5cc8199d5b1b60a21b604482015290519081900360640190fd5b6040805182815290516001600160a01b038416916000917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6001600160a01b038216600090815260208190526040902054612e42908263ffffffff61239516565b6001600160a01b038316600090815260208190526040902055600254612e6e908263ffffffff61239516565b6002556040805182815290516000916001600160a01b038516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b6000818303818312801590612ecb5750838113155b80612ee05750600083128015612ee057508381135b61249c57600080fd5b6000828201818312801590612efe5750838112155b80612ee05750600083128015612ee0575083811261249c57600080fd5b60008080612f5f612f52670de0b6b3a7640000612f4687670a688906bd8b000063ffffffff61310516565b9063ffffffff61314516565b869063ffffffff612ee916565b90506000612f8a612f52670de0b6b3a7640000612f4689670a688906bd8b000063ffffffff61310516565b9050612f9c828263ffffffff61310516565b9250612fe1612fb1888063ffffffff61310516565b612fd5670a688906bd8b0000612f4687670de0b6b3a764000063ffffffff61310516565b9063ffffffff612eb616565b9250505082612ff1576001612ff3565b825b915060006130366130216ec097ce7bc90715b34b9f1000000000670a688906bd8b000063ffffffff61314516565b670a688906bd8b00009063ffffffff612ee916565b90506000613058670de0b6b3a7640000612f468985850363ffffffff61310516565b905060005b60648110156130cf57846130878361307b878463ffffffff61314516565b9063ffffffff612ee916565b95506130a46002612f468861307b87818b8463ffffffff61314516565b9550600a8682031280156130bb5750600919868203135b156130c657506130cf565b5060010161305d565b506130e181600263ffffffff61314516565b8412156130fb576130f8818563ffffffff612eb616565b93505b5050509392505050565b600082613114575060006106fc565b8282028284828161312157fe5b05148015612ee0575083600019141580612ee0575060fe1983141561249c57600080fd5b6000811580159061315857508160001914155b8015613166575060fe198314155b61316f57600080fd5b600082848161317a57fe5b0594935050505056fe9b637c76efb0cd7c4fd209e3a1729df7cd805083f76aebc6077dac5bc8e1f0900000000000000000000000005d3a536e4d6dbd6114cc1ead35777bab948e36430000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000039aa39c021dfbae8fac545936693ac917d5e7563a265627a7a7231582040a591981c372d6b7056bf261c711c09fa1088e61c1bc89f012563047befd73564736f6c63430005100032

Verified Source Code Partial Match

Compiler: v0.5.16+commit.9c3226ce EVM: istanbul Optimization: Yes (200 runs)
bhsAlpha.sol 621 lines
pragma solidity ^0.5.16;

library SafeMath {

    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) 
            return 0;
        uint256 c = a * b;
        require(c / a == b);
        return c;
    }

    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0);
        uint256 c = a / b;
        return c;
    }

    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a);
        uint256 c = a - b;
        return c;
    }

    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a);
        return c;
    }

    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0);
        return a % b;
    }

    int256 constant private INT256_MIN = -2^255;

    function mul(int256 a, int256 b) internal pure returns (int256) {
        if (a == 0) 
            return 0;
        int256 c = a * b;
        require(c / a == b && (a != -1 || b != INT256_MIN));
        return c;
    }

    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0 && b != -1 && a != INT256_MIN);
        int256 c = a / b;
        return c;
    }

    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }
}


contract ERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) internal _balances;
    mapping (address => mapping (address => uint256)) internal _allowed;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    uint256 internal _totalSupply;

    /**
    * @dev Total number of tokens in existence
    */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
    * @dev Gets the balance of the specified address.
    * @param owner The address to query the balance of.
    * @return A uint256 representing the amount owned by the passed address.
    */
    function balanceOf(address owner) public view returns (uint256) {
        return _balances[owner];
    }

    /**
    * @dev Function to check the amount of tokens that an owner allowed to a spender.
    * @param owner address The address which owns the funds.
    * @param spender address The address which will spend the funds.
    * @return A uint256 specifying the amount of tokens still available for the spender.
    */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowed[owner][spender];
    }

    /**
    * @dev Transfer token to a specified address
    * @param to The address to transfer to.
    * @param value The amount to be transferred.
    */
    function transfer(address to, uint256 value) public returns (bool) {
        _transfer(msg.sender, to, value);
        return true;
    }

    /**
    * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
    * 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
    * @param spender The address which will spend the funds.
    * @param value The amount of tokens to be spent.
    */
    function approve(address spender, uint256 value) public returns (bool) {
        _allowed[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    /**
    * @dev Transfer tokens from one address to another.
    * Note that while this function emits an Approval event, this is not required as per the specification,
    * and other compliant implementations may not emit the event.
    * @param from address The address which you want to send tokens from
    * @param to address The address which you want to transfer to
    * @param value uint256 the amount of tokens to be transferred
    */
    function transferFrom(address from, address to, uint256 value) public returns (bool) {
        _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
        _transfer(from, to, value);
        return true;
    }

    function _transfer(address from, address to, uint256 value) internal {
        require(to != address(0));
        _balances[from] = _balances[from].sub(value);
        _balances[to] = _balances[to].add(value);
        emit Transfer(from, to, value);
    }

}

contract ERC20Mintable is ERC20 {
    string public name;
    string public symbol;
    uint8 public decimals;

    function _mint(address to, uint256 amount) internal {
        _balances[to] = _balances[to].add(amount);
        _totalSupply = _totalSupply.add(amount);
        require(_totalSupply <= 10000e18, "pool is full");
        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal {
        _balances[from] = _balances[from].sub(amount);
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(from, address(0), amount);
    }
}

contract CERC20 is ERC20 {
    function borrow(uint256) external returns (uint256);
    function borrowBalanceCurrent(address) external returns (uint256);
    function repayBorrow(uint256) external returns (uint256);
    function mint(uint256) external returns (uint256);
    function redeemUnderlying(uint256) external returns (uint256);
    function balanceOfUnderlying(address) external returns (uint256);
}


interface Comptroller {
    function enterMarkets(address[] calldata) external returns (uint256[] memory);
}

contract UniswapV2Router02 {
    function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts);
}

contract bhsAlpha is ERC20Mintable {
    using SafeMath for *;

    /***********************************|
    |        Variables && Events        |
    |__________________________________*/

    string public alarm = "ALPHA VERSION FOR DEVELOPER TESTING, DO NOT USE.";

    Comptroller constant comptroller = Comptroller(0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B);
    UniswapV2Router02 constant uniswap = UniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);

    ERC20 constant Comp = ERC20(0xc00e94Cb662C3520282E6f5717214004A7f26888);
    ERC20 constant Dai = ERC20(0x6B175474E89094C44Da98b954EedeAC495271d0F);
    ERC20 constant USDC = ERC20(0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48);
    CERC20 constant cDai = CERC20(0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643);
    CERC20 constant cUSDC = CERC20(0x39AA39c021dfbaE8faC545936693aC917d5E7563);

    event Purchases(address indexed buyer, address indexed buy_token, uint256 inputs, uint256 outputs);
    event AddLiquidity(address indexed provider, uint256 DAIAmount, uint256 USDCAmount);
    event RemoveLiquidity(address indexed provider, uint256 DAIAmount, uint256 USDCAmount);

    /***********************************|
    |            Constsructor           |
    |__________________________________*/

    constructor() public {
        symbol = "BHSc$";
        name = "BlackHoleSwap-Compound DAI/USDC v1";
        decimals = 18;

        Dai.approve(address(cDai), uint256(-1));
        USDC.approve(address(cUSDC), uint256(-1));
        Comp.approve(address(uniswap), uint256(-1));

        address[] memory cTokens = new address[](2);
        cTokens[0] = address(cDai);
        cTokens[1] = address(cUSDC);
        uint256[] memory errors = comptroller.enterMarkets(cTokens);
        require(errors[0] == 0 && errors[1] == 0, "Comptroller.enterMarkets failed.");

        admin = msg.sender;
    }

    /***********************************|
    |        Governmence & Params       |
    |__________________________________*/

    uint256 public fee = 0.99985e18;
    uint256 public protocolFee = 0;
    uint256 public constant amplifier = 0.75e18;

    address private admin;
    address private vault;

    function setAdmin(address _admin) external {
        require(msg.sender == admin);
        admin = _admin;
    }

    function setParams(uint256 _fee, uint256 _protocolFee) external {
        require(msg.sender == admin);
        require(_fee < 1e18 && _fee >= 0.99e18); //0 < fee <= 1%
        if(_protocolFee > 0)
            require(uint256(1e18).sub(_fee).div(_protocolFee) >= 3); //protocolFee < 33.3% fee
        fee = _fee;
        protocolFee = _protocolFee;
    }

    function setVault(address _vault) external {
        require(msg.sender == admin);
        vault = _vault;
    }

    /***********************************|
    |         Getter Functions          |
    |__________________________________*/

    function getDaiBalance() public returns (uint256, uint256) {
        if (cDai.balanceOf(address(this)) <= 10)
            return (0, cDai.borrowBalanceCurrent(address(this)));
        else
            return (cDai.balanceOfUnderlying(address(this)), cDai.borrowBalanceCurrent(address(this)));
    }

    function getUSDCBalance() public returns (uint256, uint256) {
        if (cUSDC.balanceOf(address(this)) <= 10)
            return (0, cUSDC.borrowBalanceCurrent(address(this)).mul(rate()) );
        else
            return (cUSDC.balanceOfUnderlying(address(this)).mul(rate()), cUSDC.borrowBalanceCurrent(address(this)).mul(rate()));
    }

    // DAI + USDC
    function S() public returns (uint256) {
        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();
        return(a.add(c).sub(b).sub(d));
    }

    function F(int256 _x, int256 x, int256 y) internal pure returns (int256 _y) {
        int256 k;
        {
            // u = x + ay, v = y + ax
            int256 u = x.add(y.mul(int256(amplifier)).div(1e18));
            int256 v = y.add(x.mul(int256(amplifier)).div(1e18));
            k = u.mul(v); // k = u * v
            k = k.mul(1e18).div(int256(amplifier)).sub(_x.mul(_x)); // k = k/a - x^2
        }
        
        _y = y != 0 ? y : 1;
        int256 cst = int256(amplifier).add(1e36.div(int256(amplifier))); // a + 1/a
        int256 b = _x.mul(-cst).div(1e18); //-b

        for(uint256 j = 0; j < 100; j++) {
            int256 __y = _y;
            _y = k.div(_y).add(b); // y = (k/a - x^2) / y - b
            _y = k.div(_y).add(b).add(_y).div(2); // y = ( (k/a - x^2) / y - b + y ) / 2
            if(__y - _y < 10 && __y - _y > -10) break;
        }

        if(_y < b.div(2)) // if y < -b/2, then y = -b - y
            _y = b.sub(_y);
    }

    function getInputPrice(uint256 input, uint256 a, uint256 b, uint256 c, uint256 d) public pure returns (uint256) {
        int256 x = int256(a).sub(int256(b));
        int256 y = int256(c).sub(int256(d));
        int256 _x = x.add(int256(input));

        int256 _y = F(_x, x, y);

        return uint256(y.sub(_y));
    }

    function getOutputPrice(uint256 output, uint256 a, uint256 b, uint256 c, uint256 d) public pure returns (uint256) {
        int256 x = int256(a).sub(int256(b));
        int256 y = int256(c).sub(int256(d));
        int256 _y = y.sub(int256(output));

        int256 _x = F(_y, y, x);

        return uint256(_x.sub(x));
    }

    function rate() public pure returns (uint256) {
        return 1e12;
    }

    /***********************************|
    |        Exchange Functions         |
    |__________________________________*/
    
    function calcFee(uint256 input, uint256 a, uint256 b, uint256 c, uint256 d) internal {
        if(protocolFee > 0) {
            uint256 _fee = input.mul(protocolFee).div(1e18).mul(_totalSupply).div( a.add(c).sub(b).sub(d) );
            _mint(vault, _fee);
        }
    }

    function dai2usdcIn(uint256 input, uint256 min_output, uint256 deadline) public returns (uint256) {
        require(block.timestamp <= deadline, "EXPIRED");
        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        uint256 output = getInputPrice(input.mul(fee).div(1e18), a, b, c, d);
        securityCheck(input, output, a, b, c, d);
        output = output.div(rate());
        require(output >= min_output, "SLIPPAGE_DETECTED");

        calcFee(input, a, b, c, d);

        doTransferIn(Dai, cDai, b, msg.sender, input);
        doTransferOut(USDC, cUSDC, c.div(rate()), msg.sender, output);

        emit Purchases(msg.sender, address(USDC), input, output);

        return output;
    }
    
    function usdc2daiIn(uint256 input, uint256 min_output, uint256 deadline) public returns (uint256) {
        require(block.timestamp <= deadline, "EXPIRED");
        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        uint256 output = getInputPrice(input.mul(fee).div(1e18).mul(rate()), c, d, a, b);
        securityCheck(input, output, c, d, a, b);
        require(output >= min_output, "SLIPPAGE_DETECTED");
        
        calcFee(input.mul(rate()), a, b, c, d);
        
        doTransferIn(USDC, cUSDC, d.div(rate()), msg.sender, input);
        doTransferOut(Dai, cDai, a, msg.sender, output);

        emit Purchases(msg.sender, address(Dai), input, output);

        return output;
    }

    function dai2usdcOut(uint256 max_input, uint256 output, uint256 deadline) public returns (uint256) {
        require(block.timestamp <= deadline, "EXPIRED");
        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        uint256 input = getOutputPrice(output.mul(rate()), a, b, c, d);
        securityCheck(input, output, a, b, c, d);
        input = input.mul(1e18).div(fee);
        require(input <= max_input, "SLIPPAGE_DETECTED");

        calcFee(input, a, b, c, d);

        doTransferIn(Dai, cDai, b, msg.sender, input);
        doTransferOut(USDC, cUSDC, c.div(rate()), msg.sender, output);

        emit Purchases(msg.sender, address(USDC), input, output);

        return input;
    }
    
    function usdc2daiOut(uint256 max_input, uint256 output, uint256 deadline) public returns (uint256) {
        require(block.timestamp <= deadline, "EXPIRED");
        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        uint256 input = getOutputPrice(output, c, d, a, b);
        securityCheck(input, output, c, d, a, b);
        input = input.mul(1e18).div(fee).div(rate());
        require(input <= max_input, "SLIPPAGE_DETECTED");

        calcFee(input.mul(rate()), a, b, c, d);

        doTransferIn(USDC, cUSDC, d.div(rate()), msg.sender, input);
        doTransferOut(Dai, cDai, a, msg.sender, output);

        emit Purchases(msg.sender, address(Dai), input, output);

        return input;
    }
    
    function doTransferIn(ERC20 token, CERC20 ctoken, uint256 debt, address from, uint256 amount) internal {
        require(token.transferFrom(from, address(this), amount));

        if(debt > 0) {
            if(debt >= amount) {
                require(ctoken.repayBorrow(amount) == 0, "ctoken.repayBorrow failed");
            }
            else {
                require(ctoken.repayBorrow(debt) == 0, "ctoken.repayBorrow failed");
                require(ctoken.mint(amount.sub(debt)) == 0, "ctoken.mint failed");
            }
        }
        else {
            require(ctoken.mint(amount) == 0, "ctoken.mint failed");
        }
    }

    function doTransferOut(ERC20 token, CERC20 ctoken, uint256 balance, address to, uint256 amount) internal {
        if(balance >= amount) {
            require(ctoken.redeemUnderlying(amount) == 0, "ctoken.redeemUnderlying failed");
        }
        else {
            if(balance == 0) {
                require(ctoken.borrow(amount) == 0, "ctoken.borrow failed");
            }
            else {
                require(ctoken.redeemUnderlying(balance) == 0, "ctoken.redeemUnderlying failed");
                require(ctoken.borrow(amount.sub(balance)) == 0, "ctoken.borrow failed");
            }
        }

        require(token.transfer(to, amount));
    }

    function securityCheck(uint256 input, uint256 output, uint256 a, uint256 b, uint256 c, uint256 d) internal pure {
        if(c < output.add(d))
            require(output.add(d).sub(c).mul(100) < input.add(a).sub(b).mul(62), "DEBT_TOO_MUCH"); // debt/collateral < 62%
    }

    /***********************************|
    |        Liquidity Functions        |
    |__________________________________*/

    function addLiquidity(uint256 share, uint256[2] memory tokens) public returns (uint256, uint256) {
        require(share >= 1e15, 'INVALID_ARGUMENT'); // 1000 * rate()

        collectComp();

        if (_totalSupply > 0) {
            (uint256 a, uint256 b) = getDaiBalance();
            (uint256 c, uint256 d) = getUSDCBalance();

            if(a < b) {
                uint256 dai_reserve = b.sub(a);
                uint256 usdc_reserve = c.sub(d);
                uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
                uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
                usdc_amount = usdc_amount.div(rate());
                require(dai_amount >= tokens[0] && usdc_amount <= tokens[1], "SLIPPAGE_DETECTED");

                _mint(msg.sender, share);
                doTransferIn(USDC, cUSDC, d.div(rate()), msg.sender, usdc_amount);
                doTransferOut(Dai, cDai, a, msg.sender, dai_amount);
                
                emit AddLiquidity(msg.sender, dai_amount, usdc_amount);
                return (dai_amount, usdc_amount);

            }
            else if (c < d) {
                uint256 dai_reserve = a.sub(b);
                uint256 usdc_reserve = d.sub(c);
                uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
                uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
                usdc_amount = usdc_amount.div(rate());
                require(dai_amount <= tokens[0] && usdc_amount >= tokens[1], "SLIPPAGE_DETECTED");

                _mint(msg.sender, share);
                doTransferIn(Dai, cDai, b, msg.sender, dai_amount);
                doTransferOut(USDC, cUSDC, c.div(rate()), msg.sender, usdc_amount);
                
                emit AddLiquidity(msg.sender, dai_amount, usdc_amount);
                return (dai_amount, usdc_amount);

            }
            else {
                uint256 dai_reserve = a.sub(b);
                uint256 usdc_reserve = c.sub(d);
                uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
                uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
                usdc_amount = usdc_amount.div(rate());
                require(dai_amount <= tokens[0] && usdc_amount <= tokens[1], "SLIPPAGE_DETECTED");

                _mint(msg.sender, share);
                doTransferIn(Dai, cDai, b, msg.sender, dai_amount);
                doTransferIn(USDC, cUSDC, d.div(rate()), msg.sender, usdc_amount);
                
                emit AddLiquidity(msg.sender, dai_amount, usdc_amount);
                return (dai_amount, usdc_amount);
            }
        } else {
            uint256 dai_amount = share.div(2);
            uint256 usdc_amount = share.div(rate()).div(2);

            _mint(msg.sender, share);
            doTransferIn(Dai, cDai, 0, msg.sender, dai_amount);
            doTransferIn(USDC, cUSDC, 0, msg.sender, usdc_amount);
            
            emit AddLiquidity(msg.sender, dai_amount, usdc_amount);
            return (dai_amount, usdc_amount);
        }
    }

    function removeLiquidity(uint256 share, uint256[2] memory tokens) public returns (uint256, uint256) {
        require(share > 0, 'INVALID_ARGUMENT');

        collectComp();

        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        if(a < b) {
            uint256 dai_reserve = b.sub(a);
            uint256 usdc_reserve = c.sub(d);
            uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
            uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
            usdc_amount = usdc_amount.div(rate());
            require(dai_amount <= tokens[0] && usdc_amount >= tokens[1], "SLIPPAGE_DETECTED");

            _burn(msg.sender, share);            
            doTransferIn(Dai, cDai, b, msg.sender, dai_amount);
            doTransferOut(USDC, cUSDC, c.div(rate()), msg.sender, usdc_amount);
            
            emit RemoveLiquidity(msg.sender, dai_amount, usdc_amount);
            return (dai_amount, usdc_amount);

        }
        else if (c < d) {
            uint256 dai_reserve = a.sub(b);
            uint256 usdc_reserve = d.sub(c);
            uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
            uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
            usdc_amount = usdc_amount.div(rate());
            require(dai_amount >= tokens[0] && usdc_amount <= tokens[1], "SLIPPAGE_DETECTED");

            _burn(msg.sender, share);
            doTransferIn(USDC, cUSDC, d.div(rate()), msg.sender, usdc_amount);
            doTransferOut(Dai, cDai, a, msg.sender, dai_amount);
            
            emit RemoveLiquidity(msg.sender, dai_amount, usdc_amount);
            return (dai_amount, usdc_amount);

        }
        else {
            uint256 dai_reserve = a.sub(b);
            uint256 usdc_reserve = c.sub(d);
            uint256 dai_amount = share.mul(dai_reserve).div(_totalSupply);
            uint256 usdc_amount = share.mul(usdc_reserve).div(_totalSupply);
            usdc_amount = usdc_amount.div(rate());
            require(dai_amount >= tokens[0] && usdc_amount >= tokens[1], "SLIPPAGE_DETECTED");

            _burn(msg.sender, share);
            doTransferOut(Dai, cDai, a, msg.sender, dai_amount);
            doTransferOut(USDC, cUSDC, c.div(rate()), msg.sender, usdc_amount);
            
            emit RemoveLiquidity(msg.sender, dai_amount, usdc_amount);
            return (dai_amount, usdc_amount);
        }
    }

    /***********************************|
    |           Collect Comp            |
    |__________________________________*/

    function collectComp() public {
        uint256 _comp = Comp.balanceOf(address(this));
        if(_comp == 0) return;

        (uint256 a, uint256 b) = getDaiBalance();
        (uint256 c, uint256 d) = getUSDCBalance();

        bool isDai = a.add(d) > c.add(b);

        address[] memory path = new address[](3);
        path[0] = address(Comp);
        path[1] = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; //weth
        path[2] = isDai ? address(Dai) : address(USDC);
        uint256[] memory amounts = uniswap.swapExactTokensForTokens(_comp, 0, path, address(this), now);

        if(isDai)
            require(cDai.mint(amounts[2]) == 0, "ctoken.mint failed");
        else
            require(cUSDC.mint(amounts[2]) == 0, "ctoken.mint failed");

    }

}

Read Contract

alarm 0xbb7e8c28 → string
allowance 0xdd62ed3e → uint256
amplifier 0x671d1c06 → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
fee 0xddca3f43 → uint256
getInputPrice 0x9eb120c0 → uint256
getOutputPrice 0xf5f5de05 → uint256
name 0x06fdde03 → string
protocolFee 0xb0e21e8a → uint256
rate 0x2c4e722e → uint256
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256

Write Contract 16 functions

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

S 0x4be1c796
No parameters
returns: uint256
addLiquidity 0x6adadd35
uint256 share
uint256[2] tokens
returns: uint256, uint256
approve 0x095ea7b3
address spender
uint256 value
returns: bool
collectComp 0xcb4a785e
No parameters
dai2usdcIn 0xbf1ab214
uint256 input
uint256 min_output
uint256 deadline
returns: uint256
dai2usdcOut 0xe1c3d3a4
uint256 max_input
uint256 output
uint256 deadline
returns: uint256
getDaiBalance 0x5ddc916a
No parameters
returns: uint256, uint256
getUSDCBalance 0x3cfd1ccc
No parameters
returns: uint256, uint256
removeLiquidity 0x94edaa63
uint256 share
uint256[2] tokens
returns: uint256, uint256
setAdmin 0x704b6c02
address _admin
setParams 0xc0324c77
uint256 _fee
uint256 _protocolFee
setVault 0x6817031b
address _vault
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
usdc2daiIn 0x26882737
uint256 input
uint256 min_output
uint256 deadline
returns: uint256
usdc2daiOut 0x90900356
uint256 max_input
uint256 output
uint256 deadline
returns: uint256

Recent Transactions

This address has 1 on-chain transactions, but only <1% of the chain is indexed. Transactions will appear as indexing progresses. View on Etherscan →