Address Contract Partially Verified
Address
0x4BCafe6C4147E640eD467290cEB6F658187a6E91
Balance
0.027906 ETH
Nonce
1
Code Size
9640 bytes
Creator
0xD8d71629...5866 at tx 0x08f1b705...e9689b
Indexed Transactions
0
Contract Bytecode
9640 bytes
0x6080604052600436106100f35760003560e01c806397cf5e851161008a578063cb85ce6711610059578063cb85ce6714610424578063d7628cb914610455578063da09c72c14610488578063ec9790821461049d576100f3565b806397cf5e85146102e2578063a0eefff014610339578063c1ec95c01461037d578063c717978f146103ea576100f3565b806333763d9a116100c657806333763d9a1461021557806342edd8e01461023f5780635bdc609b1461027257806379c7ba5d146102ae576100f3565b8063042bbe3a146100f85780630fe31eb1146101265780631b54cc881461015f578063232b956c146101ac575b600080fd5b6101246004803603604081101561010e57600080fd5b506001600160a01b0381351690602001356104b2565b005b34801561013257600080fd5b506101246004803603604081101561014957600080fd5b506001600160a01b0381351690602001356105d8565b34801561016b57600080fd5b5061019a6004803603604081101561018257600080fd5b506001600160a01b03813581169160200135166106d6565b60408051918252519081900360200190f35b3480156101b857600080fd5b506101d6600480360360208110156101cf57600080fd5b50356106f3565b604080516001600160a01b0390951685526001600160601b039384166020860152919092168382015261ffff9091166060830152519081900360800190f35b34801561022157600080fd5b5061019a6004803603602081101561023857600080fd5b5035610749565b34801561024b57600080fd5b506101246004803603602081101561026257600080fd5b50356001600160a01b031661075b565b6101246004803603608081101561028857600080fd5b5080359063ffffffff6020820135169062ffffff60408201358116916060013516610808565b3480156102ba57600080fd5b50610124600480360360408110156102d157600080fd5b508035906020013561ffff16610c7c565b3480156102ee57600080fd5b506101246004803603608081101561030557600080fd5b5080356001600160a01b03169060208101356001600160601b03908116916040810135909116906060013561ffff16610d13565b610124600480360360a081101561034f57600080fd5b5080359063ffffffff6020820135169062ffffff604082013581169160608101359091169060800135610ee0565b34801561038957600080fd5b506103ad600480360360408110156103a057600080fd5b5080359060200135611331565b6040805163ffffffff909516855262ffffff938416602086015291909216838201526001600160a01b039091166060830152519081900360800190f35b6101246004803603608081101561040057600080fd5b5080359063ffffffff6020820135169062ffffff604082013516906060013561138b565b34801561043057600080fd5b506104396119d5565b604080516001600160a01b039092168252519081900360200190f35b34801561046157600080fd5b506101246004803603602081101561047857600080fd5b50356001600160a01b03166119e4565b34801561049457600080fd5b50610439611a91565b3480156104a957600080fd5b5061019a611aa0565b336001600160a01b03831661051c576001600160a01b038082166000908152600260209081526040808320938716835292905220546104f19034611aa6565b6001600160a01b03808316600090815260026020908152604080832093881683529290522055610588565b6105316001600160a01b038416823085611aef565b6001600160a01b038082166000908152600260209081526040808320938716835292905220546105619083611aa6565b6001600160a01b038083166000908152600260209081526040808320938816835292905220555b826001600160a01b0316816001600160a01b03167f58aaa25e49f6db631eebde1d004a0f3cb1cae2cb4008f61d5e6a7081e0e2ea0a846040518082815260200191505060405180910390a3505050565b3360008181526002602090815260408083206001600160a01b03871684529091529020546106069083611b4f565b6001600160a01b03808316600090815260026020908152604080832093881680845293909152902091909155610672576040516001600160a01b0382169083156108fc029084906000818181858888f1935050505015801561066c573d6000803e3d6000fd5b50610686565b6106866001600160a01b0384168284611b94565b826001600160a01b0316816001600160a01b03167f0586cc6cb62e10f10d84ac63e536d8276b8ab868d370ff7744566a4137316fc3846040518082815260200191505060405180910390a3505050565b600260209081526000928352604080842090915290825290205481565b6003818154811061070057fe5b6000918252602090912060029091020180546001909101546001600160a01b03821692506001600160601b03600160a01b90920482169181169061ffff600160601b9091041684565b60009081526004602052604090205490565b6000546001600160a01b031633146107a3576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b6001600160a01b0381166107e6576040805162461bcd60e51b815260206004820152600560248201526410b0b2323960d91b604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008262ffffff161161084e576040805162461bcd60e51b81526020600482015260096024820152682170726963654c6f7760b81b604482015290519081900360640190fd5b60008162ffffff1611610895576040805162461bcd60e51b815260206004820152600a602482015269042e0e4d2c6ca90d2ced60b31b604482015290519081900360640190fd5b8162ffffff168162ffffff1610156108e2576040805162461bcd60e51b815260206004820152600b60248201526a21707269636552616e676560a81b604482015290519081900360640190fd5b600184166108ee612521565b600360028704815481106108fe57fe5b600091825260209182902060408051608081018252600290930290910180546001600160a01b0381168085526001600160601b03600160a01b9092048216958501959095526001909101549081169183019190915261ffff600160601b90910416606082015291506109a1576040805162461bcd60e51b8152602060048201526007602482015266085b585c9ad95d60ca1b604482015290519081900360640190fd5b338215610a2c57600082604001516002026001600160601b03168562ffffff168762ffffff160184602001516001600160601b03168963ffffffff160202816109e657fe5b049050803414610a26576040805162461bcd60e51b81526020600480830191909152602482015263042cae8d60e31b604482015290519081900360640190fd5b50610aad565b815163ffffffff871615610a6f57610a6f823085602001516001600160601b03168a63ffffffff1602846001600160a01b0316611aef909392919063ffffffff16565b3415610aab576040805162461bcd60e51b81526020600480830191909152602482015263042cae8d60e31b604482015290519081900360640190fd5b505b610ab5612521565b8181606001906001600160a01b031690816001600160a01b03168152505086816000019063ffffffff16908163ffffffff168152505085816020019062ffffff16908162ffffff168152505084816040019062ffffff16908162ffffff16815250506000600460008a8152602001908152602001600020905080829080600181540180825580915050600190039060005260206000200160009091909190915060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a81548162ffffff021916908362ffffff16021790555060408201518160000160076101000a81548162ffffff021916908362ffffff160217905550606082015181600001600a6101000a8154816001600160a01b0302191690836001600160a01b031602179055505050600060018280549050039050600060388862ffffff16901b62ffffff1660208a62ffffff16901b62ffffff168b171763ffffffff169050818b866001600160a01b03167f219ffa51265844bd01d3b42f033eed7742d9447a7237f1b733f3dbcae03dfe72846040518082815260200191505060405180910390a45050505050505050505050565b6000546001600160a01b03163314610cc4576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b603c8161ffff161115610cd657600080fd5b8060038381548110610ce457fe5b9060005260206000209060020201600101600c6101000a81548161ffff021916908361ffff1602179055505050565b6000546001600160a01b03163314610d5b576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b6000836001600160601b031611610d7157600080fd5b6000826001600160601b031611610d8757600080fd5b603c8161ffff161115610d9957600080fd5b610da1612521565b6001600160a01b038086168083526001600160601b038087166020808601828152888416604080890182815261ffff808c1660608c019081526003805460018101825560008290528d5160029091027fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b8101805499518d16600160a01b02928f166001600160a01b0319909a1699909917909d161790965591517fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85c909a0180549251909116600160601b0261ffff60601b199a9098166bffffffffffffffffffffffff1990921691909117989098169590951790965554835192835290820194909452815160001994909401937f6519feb3e6be8989ebf94368dcc591b9635818a96e48eb37719b4c364b69c214929181900390910190a35050505050565b60008362ffffff1611610f26576040805162461bcd60e51b81526020600482015260096024820152682170726963654c6f7760b81b604482015290519081900360640190fd5b60008262ffffff1611610f6d576040805162461bcd60e51b815260206004820152600a602482015269042e0e4d2c6ca90d2ced60b31b604482015290519081900360640190fd5b8262ffffff168262ffffff161015610fba576040805162461bcd60e51b815260206004820152600b60248201526a21707269636552616e676560a81b604482015290519081900360640190fd5b600085815260046020526040812080543392919084908110610fd857fe5b600091825260209091200180549091506001600160a01b03838116600160501b9092041614611036576040805162461bcd60e51b815260206004820152600560248201526410bab9b2b960d91b604482015290519081900360640190fd5b60018716611042612521565b600360028a048154811061105257fe5b60009182526020918290206040805160808101825260029390930290910180546001600160a01b0381168452600160a01b90046001600160601b03908116948401949094526001015492831690820152600160601b90910461ffff166060820152905081156111ab576040810151835460208301516000926001600160601b03600290910281169263ffffffff81169190921602600160201b820462ffffff908116600160381b9093041691909101028161110957fe5b049050600082604001516002026001600160601b03168862ffffff168a62ffffff160184602001516001600160601b03168c63ffffffff1602028161114a57fe5b04905060006111638261115d3486611aa6565b90611b4f565b905080156111a3576040516001600160a01b0388169082156108fc029083906000818181858888f193505050501580156111a1573d6000803e3d6000fd5b505b505050611251565b6020810151835482516001600160601b0390921663ffffffff918216810292918b160290828211156111f3576111ee6001600160a01b0382168830868603611aef565b611211565b82821015611211576112116001600160a01b03821688848603611b94565b341561124d576040805162461bcd60e51b81526020600480830191909152602482015263042cae8d60e31b604482015290519081900360640190fd5b5050505b825463ffffffff89811691161461127657825463ffffffff191663ffffffff89161783555b825462ffffff888116600160201b90920416146112a957825466ffffff000000001916600160201b62ffffff8916021783555b825462ffffff878116600160381b90920416146112db57825462ffffff60381b1916600160381b62ffffff8816021783555b6040805163ffffffff8a16808252915187918c916001600160a01b038916917fbfae90e027bbda5ea36db1fb40d3f291424a5336695de8b99136e7093e45d3f3919081900360200190a450505050505050505050565b6004602052816000526040600020818154811061134a57fe5b60009182526020909120015463ffffffff8116925062ffffff600160201b820481169250600160381b820416906001600160a01b03600160501b9091041684565b60008481526004602052604081208054839081106113a557fe5b90600052602060002001905060008463ffffffff16116113f5576040805162461bcd60e51b8152602060048083019190915260248201526308585b5d60e21b604482015290519081900360640190fd5b805463ffffffff16611437576040805162461bcd60e51b8152602060048083019190915260248201526308585b5d60e21b604482015290519081900360640190fd5b80543390600160501b90046001600160a01b031660018716611457612521565b600360028a048154811061146757fe5b6000918252602080832060408051608081018252600290940290910180546001600160a01b0381168086526001600160601b03600160a01b9092048216948601949094526001909101549081169184019190915261ffff600160601b909104166060830152875491935091908190600160201b810462ffffff908116600160381b90920416141561160e578754600160201b900462ffffff16851561154e578a62ffffff16811015611549576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b611591565b8a62ffffff16811115611591576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b885463ffffffff808e169450168311156115b057885463ffffffff1692505b84604001516001600160601b03168186602001516001600160601b0316850202816115d757fe5b8a5491900492506115f39063ffffffff908116908590611b4f16565b895463ffffffff191663ffffffff9190911617895550611677565b875462ffffff600160201b82048116600160381b9092041611611664576040805162461bcd60e51b815260206004820152600960248201526810b130b227b93232b960b91b604482015290519081900360640190fd5b6116718885878e8e611beb565b90925090505b600082116116c2576040805162461bcd60e51b815260206004820152601360248201527208599a5b1b151bdad95b905b5d14d8d85b1959606a1b604482015290519081900360640190fd5b60008111611705576040805162461bcd60e51b815260206004820152600b60248201526a08599a5b1b115d1a105b5d60aa1b604482015290519081900360640190fd5b60208401516001600160601b031682028515611821576117306001600160a01b038516898984611aef565b6000612710866060015161ffff1684028161174757fe5b6001546001600160a01b03166000908152600260209081526040808320838052909152902054919004915061177c9082611aa6565b6001546001600160a01b03908116600090815260026020908152604080832083805290915290209190915589166108fc6117b68584611b4f565b6040518115909202916000818181858888f193505050501580156117de573d6000803e3d6000fd5b50341561181b576040805162461bcd60e51b81526020600480830191909152602482015263042cae8d60e31b604482015290519081900360640190fd5b50611966565b8134101561185f576040805162461bcd60e51b81526020600480830191909152602482015263042cae8d60e31b604482015290519081900360640190fd5b6118736001600160a01b0385168983611b94565b6000612710866060015161ffff1684028161188a57fe5b6001546001600160a01b0316600090815260026020908152604080832083805290915290205491900491506118bf9082611aa6565b6001546001600160a01b03908116600090815260026020908152604080832083805290915290209190915588166108fc6118f98584611b4f565b6040518115909202916000818181858888f19350505050158015611921573d6000803e3d6000fd5b5082341115611964576040516001600160a01b038a16903485900380156108fc02916000818181858888f19350505050158015611962573d6000803e3d6000fd5b505b505b6000602083901b841790508a8e8a6001600160a01b03167f05e0db78ec0e4b398d129053215be9d7cdf64d7fa53c1c1b6c2bc780dc73bc7b8b8560405180836001600160a01b031681526020018281526020019250505060405180910390a45050505050505050505050505050565b6000546001600160a01b031681565b6000546001600160a01b03163314611a2c576040805162461bcd60e51b8152602060048083019190915260248201526310b3b7bb60e11b604482015290519081900360640190fd5b6001600160a01b038116611a6f576040805162461bcd60e51b815260206004820152600560248201526410b0b2323960d91b604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031681565b60035490565b600082820183811015611ae8576040805162461bcd60e51b8152602060048201526005602482015264084858591960da1b604482015290519081900360640190fd5b9392505050565b604080516001600160a01b0380861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611b4990859061232d565b50505050565b600082821115611b8e576040805162461bcd60e51b81526020600482015260056024820152641090b9bab160d91b604482015290519081900360640190fd5b50900390565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052611be690849061232d565b505050565b8454600090819062ffffff600160201b82048116600160381b83049091160360010190829063ffffffff908116908716830281611c2457fe5b04905081811115611c325750805b861561204257885462ffffff600160381b90910481169086161115611c87576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b8854600090611ca290600160381b900462ffffff1683611b4f565b8a54909150600160381b900462ffffff9081169087166002021115611ce6578954600160381b900462ffffff9081169087166002020380821015611ce4578091505b505b8954600160381b900462ffffff16811115611d31576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b895463ffffffff90811690881610801590611d5957508954600160201b900462ffffff168111155b15611dbf57895460408a015160208b015163ffffffff8316975060029091026001600160601b0390811692600160381b810462ffffff908116600160201b9092041601911687020281611da857fe5b8b5463ffffffff19168c5504935061232392505050565b895460208a015160009162ffffff600160381b82041684900391869163ffffffff1683026001600160601b039091160281611df657fe5b0491505089604001516002026001600160601b0316828c60000160079054906101000a900462ffffff1662ffffff1601600101820281611e3257fe5b0494506000611e5f828c602001516001600160601b03168b63ffffffff1602611b4f90919063ffffffff16565b60208c01518d5491925060009187916001600160601b031663ffffffff9091160281611e8757fe5b04905080821115611e96578091505b508a602001516001600160601b031681830181611eaf57fe5b049650611ed4828c602001516001600160601b03168902611b4f90919063ffffffff16565b9050611efa8b604001516001600160601b031684830281611ef157fe5b88919004611aa6565b60208c01518d54919750600093506001600160601b03169150611f289063ffffffff908116908990611b4f16565b60408c01518d5460208e01519290930292611f7a92600160381b820462ffffff908116600160201b840491909116016001600160601b0391821663ffffffff93841602029260020216890290611b4f16565b81611f8157fe5b8c549190049150611f9f908290600160201b900462ffffff16611b4f565b8b54909150600160201b900462ffffff16811015611ff5576040805162461bcd60e51b815260206004820152600e60248201526d2162616446696e616c52616e676560901b604482015290519081900360640190fd5b8a5462ffffff60381b1916600160381b62ffffff83160217808c556120259063ffffffff908116908890611b4f16565b8b5463ffffffff191663ffffffff91909116178b55506123209050565b885462ffffff600160201b90910481169086161015612091576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b88546000906120ac90600160201b900462ffffff1683611aa6565b8a549091506000906120d09062ffffff89811660020291600160201b900416611b4f565b9050808211156120de578091505b508954600160201b900462ffffff1681101561212a576040805162461bcd60e51b815260206004820152600660248201526521707269636560d01b604482015290519081900360640190fd5b895463ffffffff9081169088161080159061215257508954600160381b900462ffffff168110155b156121a157895460408a015160208b015163ffffffff8316975060029091026001600160601b0390811692600160381b810462ffffff908116600160201b9092041601911687020281611da857fe5b895460208a015160009162ffffff600160201b820416840391869163ffffffff1683026001600160601b0390911602816121d757fe5b0491505089604001516002026001600160601b03166001838d60000160049054906101000a900462ffffff1662ffffff16010382028161221357fe5b0494506000612240828c602001516001600160601b03168b63ffffffff1602611b4f90919063ffffffff16565b60208c01518d5491925060009187916001600160601b031663ffffffff909116028161226857fe5b04905080821115612277578091505b508a602001516001600160601b03168183018161229057fe5b0496506122b5828c602001516001600160601b03168902611b4f90919063ffffffff16565b90506122d28b604001516001600160601b031684830281611ef157fe5b8c549096506122ee925063ffffffff90811691508790611b4f16565b8a5463ffffffff191663ffffffff919091161766ffffff000000001916600160201b62ffffff92909216919091021789555b50505b9550959350505050565b61233f826001600160a01b03166124e5565b612390576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106123ce5780518252601f1990920191602091820191016123af565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612430576040519150601f19603f3d011682016040523d82523d6000602084013e612435565b606091505b50915091508161248c576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b805115611b49578080602001905160208110156124a857600080fd5b5051611b495760405162461bcd60e51b815260040180806020018281038252602a815260200180612549602a913960400191505060405180910390fd5b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906125195750808214155b949350505050565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122027db567a69e2cd1271882b6301e44f31d93acaf01e6542df89ba27456154205164736f6c634300060c0033
Verified Source Code Partial Match
Compiler: v0.6.12+commit.27d51765
EVM: istanbul
Optimization: Yes (200 runs)
KittenSwapV01.sol 542 lines
// _ _ _ _ __ _
// | | (_) | | | / _(_)
// | | ___| |_| |_ ___ _ __ | |_ _ _ __ __ _ _ __ ___ ___
// | |/ / | __| __/ _ \ '_ \ | _| | '_ \ / _` | '_ \ / __/ _ \
// | <| | |_| || __/ | | |_| | | | | | | (_| | | | | (_| __/
// |_|\_\_|\__|\__\___|_| |_(_)_| |_|_| |_|\__,_|_| |_|\___\___|
//
// KittenSwap v0.1
//
// https://www.KittenSwap.org/
//
pragma solidity ^0.6.12;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "!!add");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "!!sub");
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "!!mul");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "!!div");
uint256 c = a / b;
return c;
}
}
interface IERC20 {
function transfer(address recipient, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}
library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
}
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 callOptionalReturn(IERC20 token, bytes memory data) private {
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");
}
}
}
////////////////////////////////////////////////////////////////////////////////
contract KittenSwapV01
{
using SafeMath for uint256;
using SafeERC20 for IERC20;
////////////////////////////////////////////////////////////////////////////////
address public govAddr;
address public devAddr;
constructor () public {
govAddr = msg.sender;
devAddr = msg.sender;
}
modifier govOnly()
{
require(msg.sender == govAddr, "!gov");
_;
}
function govTransferAddr(address newAddr) external govOnly
{
require(newAddr != address(0), "!addr");
govAddr = newAddr;
}
modifier devOnly()
{
require(msg.sender == devAddr, "!dev");
_;
}
function devTransferAddr(address newAddr) external govOnly
{
require(newAddr != address(0), "!addr");
devAddr = newAddr;
}
////////////////////////////////////////////////////////////////////////////////
mapping (address => mapping (address => uint)) public vault;
event VAULT_DEPOSIT(address indexed user, address indexed token, uint amt);
event VAULT_WITHDRAW(address indexed user, address indexed token, uint amt);
function vaultWithdraw(address token, uint amt) external
{
address payable user = msg.sender;
vault[user][token] = vault[user][token].sub(amt);
if (token == address(0)) {
user.transfer(amt);
} else {
IERC20(token).safeTransfer(user, amt);
}
emit VAULT_WITHDRAW(user, token, amt);
}
function vaultDeposit(address token, uint amt) external payable
{
address user = msg.sender;
if (token == address(0)) {
vault[user][token] = vault[user][token].add(msg.value);
} else {
IERC20(token).safeTransferFrom(user, address(this), amt);
vault[user][token] = vault[user][token].add(amt);
}
emit VAULT_DEPOSIT(user, token, amt);
}
////////////////////////////////////////////////////////////////////////////////
struct MARKET {
address token; // fixed after creation
uint96 AMT_SCALE; // fixed after creation
uint96 PRICE_SCALE; // fixed after creation
uint16 DEVFEE_BP; // in terms of basis points (1 bp = 0.01%)
}
MARKET[] public marketList;
event MARKET_CREATE(address indexed token, uint96 $AMT_SCALE, uint96 $PRICE_SCALE, uint indexed id);
function govCreateMarket(address $token, uint96 $AMT_SCALE, uint96 $PRICE_SCALE, uint16 $DEVFEE_BP) external govOnly
{
require ($AMT_SCALE > 0);
require ($PRICE_SCALE > 0);
require ($DEVFEE_BP <= 60);
MARKET memory m;
m.token = $token;
m.AMT_SCALE = $AMT_SCALE;
m.PRICE_SCALE = $PRICE_SCALE;
m.DEVFEE_BP = $DEVFEE_BP;
marketList.push(m);
emit MARKET_CREATE($token, $AMT_SCALE, $PRICE_SCALE, marketList.length - 1);
}
function govSetDevFee(uint $marketId, uint16 $DEVFEE_BP) external govOnly
{
require ($DEVFEE_BP <= 60);
marketList[$marketId].DEVFEE_BP = $DEVFEE_BP;
}
////////////////////////////////////////////////////////////////////////////////
struct ORDER {
uint32 tokenAmtScaled; // scaled by AMT_SCALE SCALE 10^12 => 1 ~ 2^32-1 means 0.000001 ~ 4294.967295
uint24 priceLowScaled; // scaled by PRICE_SCALE SCALE 10^4 => 1 ~ 2^24-1 means 0.0001 ~ 1677.7215
uint24 priceHighScaled; // scaled by PRICE_SCALE SCALE 10^4 => 1 ~ 2^24-1 means 0.0001 ~ 1677.7215
uint160 userMaker;
}
mapping (uint => ORDER[]) public orderList; // div 2 = market, mod 2 = 0 sell, 1 buy
uint constant UINT32_MAX = 2**32 - 1;
event ORDER_CREATE(address indexed userMaker, uint indexed marketIsBuy, uint orderInfo, uint indexed orderId);
event ORDER_MODIFY(address indexed userMaker, uint indexed marketIsBuy, uint newOrderInfo, uint indexed orderId);
event ORDER_TRADE(address indexed userTaker, address userMaker, uint indexed marketIsBuy, uint fillOrderInfo, uint indexed orderId);
////////////////////////////////////////////////////////////////////////////////
function marketCount() external view returns (uint)
{
return marketList.length;
}
function orderCount(uint $marketIsBuy) external view returns (uint)
{
return orderList[$marketIsBuy].length;
}
////////////////////////////////////////////////////////////////////////////////
function orderCreate(uint $marketIsBuy, uint32 $tokenAmtScaled, uint24 $priceLowScaled, uint24 $priceHighScaled) external payable
{
require($priceLowScaled > 0, "!priceLow");
require($priceHighScaled > 0, "!priceHigh");
require($priceHighScaled >= $priceLowScaled, "!priceRange");
uint isMakerBuy = $marketIsBuy % 2;
MARKET memory m = marketList[$marketIsBuy / 2];
require(m.token != address(0), "!market");
//------------------------------------------------------------------------------
address userMaker = msg.sender;
if (isMakerBuy > 0) // buy token -> deposit ETH
{
uint ethAmt = uint($tokenAmtScaled) * uint(m.AMT_SCALE) * (uint($priceLowScaled) + uint($priceHighScaled)) / uint(m.PRICE_SCALE * 2);
require(msg.value == ethAmt, '!eth');
}
else // sell token -> deposit token
{
IERC20 token = IERC20(m.token);
if ($tokenAmtScaled > 0)
token.safeTransferFrom(userMaker, address(this), uint($tokenAmtScaled) * uint(m.AMT_SCALE));
require(msg.value == 0, '!eth');
}
//------------------------------------------------------------------------------
ORDER memory o;
o.userMaker = uint160(userMaker);
o.tokenAmtScaled = $tokenAmtScaled;
o.priceLowScaled = $priceLowScaled;
o.priceHighScaled = $priceHighScaled;
//------------------------------------------------------------------------------
ORDER[] storage oList = orderList[$marketIsBuy];
oList.push(o);
uint orderId = oList.length - 1;
uint orderInfo = $tokenAmtScaled | ($priceLowScaled<<32) | ($priceHighScaled<<(32+24));
emit ORDER_CREATE(userMaker, $marketIsBuy, orderInfo, orderId);
}
////////////////////////////////////////////////////////////////////////////////
function orderModify(uint $marketIsBuy, uint32 newTokenAmtScaled, uint24 newPriceLowScaled, uint24 newPriceHighScaled, uint orderID) external payable
{
require(newPriceLowScaled > 0, "!priceLow");
require(newPriceHighScaled > 0, "!priceHigh");
require(newPriceHighScaled >= newPriceLowScaled, "!priceRange");
address payable userMaker = msg.sender;
ORDER storage o = orderList[$marketIsBuy][orderID];
require (uint160(userMaker) == o.userMaker, "!user");
uint isMakerBuy = $marketIsBuy % 2;
MARKET memory m = marketList[$marketIsBuy / 2];
//------------------------------------------------------------------------------
if (isMakerBuy > 0) // old order: maker buy token -> modify ETH amt
{
uint oldEthAmt = uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) * (uint(o.priceLowScaled) + uint(o.priceHighScaled)) / uint(m.PRICE_SCALE * 2);
uint newEthAmt = uint(newTokenAmtScaled) * uint(m.AMT_SCALE) * (uint(newPriceLowScaled) + uint(newPriceHighScaled)) / uint(m.PRICE_SCALE * 2);
uint extraEthAmt = (msg.value).add(oldEthAmt).sub(newEthAmt); // throw if not enough
if (extraEthAmt > 0)
userMaker.transfer(extraEthAmt); // return extra ETH to maker
}
else // old order: maker sell token -> modify token amt
{
uint oldTokenAmt = uint(o.tokenAmtScaled) * uint(m.AMT_SCALE);
uint newTokenAmt = uint(newTokenAmtScaled) * uint(m.AMT_SCALE);
IERC20 token = IERC20(m.token);
if (newTokenAmt > oldTokenAmt) {
token.safeTransferFrom(userMaker, address(this), newTokenAmt - oldTokenAmt);
}
else if (newTokenAmt < oldTokenAmt) {
token.safeTransfer(userMaker, oldTokenAmt - newTokenAmt); // return extra token to maker
}
require(msg.value == 0, '!eth');
}
//------------------------------------------------------------------------------
if (o.tokenAmtScaled != newTokenAmtScaled)
o.tokenAmtScaled = newTokenAmtScaled;
if (o.priceLowScaled != newPriceLowScaled)
o.priceLowScaled = newPriceLowScaled;
if (o.priceHighScaled != newPriceHighScaled)
o.priceHighScaled = newPriceHighScaled;
uint orderInfo = newTokenAmtScaled | (newPriceLowScaled<<32) | (newPriceHighScaled<<(32+24));
emit ORDER_MODIFY(userMaker, $marketIsBuy, orderInfo, orderID);
}
////////////////////////////////////////////////////////////////////////////////
function _fill_WLO(ORDER storage o, MARKET memory m, uint isMakerBuy, uint32 $tokenAmtScaled, uint24 fillPriceWorstScaled) internal returns (uint fillTokenAmtScaled, uint fillEthAmt)
{
uint allSlots = uint(1) + uint(o.priceHighScaled) - uint(o.priceLowScaled);
uint fullFillSlots = allSlots * ($tokenAmtScaled) / uint(o.tokenAmtScaled);
if (fullFillSlots > allSlots) {
fullFillSlots = allSlots;
}
if (isMakerBuy > 0) // maker buy token -> taker sell token
{
require (fillPriceWorstScaled <= o.priceHighScaled, '!price');
uint fillPriceEndScaled = uint(o.priceHighScaled).sub(fullFillSlots);
if ((uint(fillPriceWorstScaled) * 2) > (o.priceHighScaled))
{
uint _ppp = (uint(fillPriceWorstScaled) * 2) - (o.priceHighScaled);
if (fillPriceEndScaled < _ppp)
fillPriceEndScaled = _ppp;
}
require (fillPriceEndScaled <= o.priceHighScaled, '!price');
//------------------------------------------------------------------------------
if (($tokenAmtScaled >= o.tokenAmtScaled) && (fillPriceEndScaled <= o.priceLowScaled)) // full fill
{
fillTokenAmtScaled = o.tokenAmtScaled;
fillEthAmt = uint(fillTokenAmtScaled) * uint(m.AMT_SCALE) * (uint(o.priceLowScaled) + uint(o.priceHighScaled)) / uint(m.PRICE_SCALE * 2);
o.tokenAmtScaled = 0;
return (fillTokenAmtScaled, fillEthAmt);
}
//------------------------------------------------------------------------------
{
uint fillTokenAmtFirst = 0; // full fill @ [fillPriceEndScaled+1, priceHighScaled]
{
uint firstFillSlots = uint(o.priceHighScaled) - uint(fillPriceEndScaled);
fillTokenAmtFirst = firstFillSlots * uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) / allSlots;
}
fillEthAmt = fillTokenAmtFirst * (uint(o.priceHighScaled) + uint(fillPriceEndScaled) + 1) / uint(m.PRICE_SCALE * 2);
uint fillTokenAmtSecond = (uint($tokenAmtScaled) * uint(m.AMT_SCALE)).sub(fillTokenAmtFirst); // partial fill @ fillPriceEndScaled
{
uint amtPerSlot = uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) / allSlots;
if (fillTokenAmtSecond > amtPerSlot) {
fillTokenAmtSecond = amtPerSlot;
}
}
fillTokenAmtScaled = (fillTokenAmtFirst + fillTokenAmtSecond) / uint(m.AMT_SCALE);
fillTokenAmtSecond = (fillTokenAmtScaled * uint(m.AMT_SCALE)).sub(fillTokenAmtFirst);
fillEthAmt = fillEthAmt.add(fillTokenAmtSecond * fillPriceEndScaled / uint(m.PRICE_SCALE));
}
//------------------------------------------------------------------------------
uint newPriceHighScaled =
(
( uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) * (uint(o.priceLowScaled) + uint(o.priceHighScaled)) )
.sub
( fillEthAmt * uint(m.PRICE_SCALE * 2) )
)
/
( (uint(o.tokenAmtScaled).sub(fillTokenAmtScaled)) * uint(m.AMT_SCALE) )
;
newPriceHighScaled = newPriceHighScaled.sub(o.priceLowScaled);
require (newPriceHighScaled >= o.priceLowScaled, "!badFinalRange"); // shall never happen
o.priceHighScaled = uint24(newPriceHighScaled);
o.tokenAmtScaled = uint32(uint(o.tokenAmtScaled).sub(fillTokenAmtScaled));
}
//------------------------------------------------------------------------------
else // maker sell token -> taker buy token
{
require (fillPriceWorstScaled >= o.priceLowScaled, '!price');
uint fillPriceEndScaled = uint(o.priceLowScaled).add(fullFillSlots);
{
uint _ppp = (uint(fillPriceWorstScaled) * 2).sub(o.priceLowScaled);
if (fillPriceEndScaled > _ppp)
fillPriceEndScaled = _ppp;
}
require (fillPriceEndScaled >= o.priceLowScaled, '!price');
//------------------------------------------------------------------------------
if (($tokenAmtScaled >= o.tokenAmtScaled) && (fillPriceEndScaled >= o.priceHighScaled)) // full fill
{
fillTokenAmtScaled = o.tokenAmtScaled;
fillEthAmt = uint(fillTokenAmtScaled) * uint(m.AMT_SCALE) * (uint(o.priceLowScaled) + uint(o.priceHighScaled)) / uint(m.PRICE_SCALE * 2);
o.tokenAmtScaled = 0;
return (fillTokenAmtScaled, fillEthAmt);
}
//------------------------------------------------------------------------------
{
uint fillTokenAmtFirst = 0; // full fill @ [priceLowScaled, fillPriceEndScaled-1]
{
uint firstFillSlots = uint(fillPriceEndScaled) - uint(o.priceLowScaled);
fillTokenAmtFirst = firstFillSlots * uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) / allSlots;
}
fillEthAmt = fillTokenAmtFirst * (uint(o.priceLowScaled) + uint(fillPriceEndScaled) - 1) / uint(m.PRICE_SCALE * 2);
uint fillTokenAmtSecond = (uint($tokenAmtScaled) * uint(m.AMT_SCALE)).sub(fillTokenAmtFirst); // partial fill @ fillPriceEndScaled
{
uint amtPerSlot = uint(o.tokenAmtScaled) * uint(m.AMT_SCALE) / allSlots;
if (fillTokenAmtSecond > amtPerSlot) {
fillTokenAmtSecond = amtPerSlot;
}
}
fillTokenAmtScaled = (fillTokenAmtFirst + fillTokenAmtSecond) / uint(m.AMT_SCALE);
fillTokenAmtSecond = (fillTokenAmtScaled * uint(m.AMT_SCALE)).sub(fillTokenAmtFirst);
fillEthAmt = fillEthAmt.add(fillTokenAmtSecond * fillPriceEndScaled / uint(m.PRICE_SCALE));
}
//------------------------------------------------------------------------------
o.tokenAmtScaled = uint32(uint(o.tokenAmtScaled).sub(fillTokenAmtScaled));
o.priceLowScaled = uint24(fillPriceEndScaled);
}
}
////////////////////////////////////////////////////////////////////////////////
function orderTrade(uint $marketIsBuy, uint32 $tokenAmtScaled, uint24 fillPriceWorstScaled, uint orderID) external payable
{
ORDER storage o = orderList[$marketIsBuy][orderID];
require ($tokenAmtScaled > 0, '!amt');
require (o.tokenAmtScaled > 0, '!amt');
address payable userTaker = msg.sender;
address payable userMaker = payable(o.userMaker);
uint isMakerBuy = $marketIsBuy % 2;
MARKET memory m = marketList[$marketIsBuy / 2];
IERC20 token = IERC20(m.token);
uint fillTokenAmtScaled = 0;
uint fillEthAmt = 0;
//------------------------------------------------------------------------------
if (o.priceLowScaled == o.priceHighScaled) // simple limit order
{
uint fillPriceScaled = o.priceLowScaled;
if (isMakerBuy > 0) { // maker buy token -> taker sell token
require (fillPriceScaled >= fillPriceWorstScaled, "!price"); // sell at higher price
}
else { // maker sell token -> taker buy token
require (fillPriceScaled <= fillPriceWorstScaled, "!price"); // buy at lower price
}
//------------------------------------------------------------------------------
fillTokenAmtScaled = $tokenAmtScaled;
if (fillTokenAmtScaled > o.tokenAmtScaled)
fillTokenAmtScaled = o.tokenAmtScaled;
fillEthAmt = fillTokenAmtScaled * uint(m.AMT_SCALE) * (fillPriceScaled) / uint(m.PRICE_SCALE);
o.tokenAmtScaled = uint32(uint(o.tokenAmtScaled).sub(fillTokenAmtScaled));
}
//------------------------------------------------------------------------------
else // Wide Limit Order
{
require (o.priceHighScaled > o.priceLowScaled, '!badOrder');
(fillTokenAmtScaled, fillEthAmt) = _fill_WLO(o, m, isMakerBuy, $tokenAmtScaled, fillPriceWorstScaled); // will modify order
}
//------------------------------------------------------------------------------
require(fillTokenAmtScaled > 0, "!fillTokenAmtScaled");
require(fillEthAmt > 0, "!fillEthAmt");
uint fillTokenAmt = fillTokenAmtScaled * uint(m.AMT_SCALE);
if (isMakerBuy > 0) // maker buy token -> taker sell token
{
token.safeTransferFrom(userTaker, userMaker, fillTokenAmt); // send token to maker (from taker)
uint devFee = fillEthAmt * uint(m.DEVFEE_BP) / (10000);
vault[devAddr][address(0)] = vault[devAddr][address(0)].add(devFee);
userTaker.transfer(fillEthAmt.sub(devFee)); // send eth to taker
require(msg.value == 0, '!eth');
}
else // maker sell token -> taker buy token
{
require(msg.value >= fillEthAmt, '!eth');
token.safeTransfer(userTaker, fillTokenAmt); // send token to taker
uint devFee = fillEthAmt * uint(m.DEVFEE_BP) / (10000);
vault[devAddr][address(0)] = vault[devAddr][address(0)].add(devFee);
userMaker.transfer(fillEthAmt.sub(devFee)); // send eth to maker
if (msg.value > fillEthAmt) {
userTaker.transfer(msg.value - fillEthAmt); // return extra eth to taker
}
}
//------------------------------------------------------------------------------
uint orderInfo = fillTokenAmtScaled | fillEthAmt<<32;
emit ORDER_TRADE(userTaker, userMaker, $marketIsBuy, orderInfo, orderID);
}
}
Read Contract
devAddr 0xda09c72c → address
govAddr 0xcb85ce67 → address
marketCount 0xec979082 → uint256
marketList 0x232b956c → address, uint96, uint96, uint16
orderCount 0x33763d9a → uint256
orderList 0xc1ec95c0 → uint32, uint24, uint24, uint160
vault 0x1b54cc88 → uint256
Write Contract 9 functions
These functions modify contract state and require a wallet transaction to execute.
devTransferAddr 0xd7628cb9
address newAddr
govCreateMarket 0x97cf5e85
address $token
uint96 $AMT_SCALE
uint96 $PRICE_SCALE
uint16 $DEVFEE_BP
govSetDevFee 0x79c7ba5d
uint256 $marketId
uint16 $DEVFEE_BP
govTransferAddr 0x42edd8e0
address newAddr
orderCreate 0x5bdc609b
uint256 $marketIsBuy
uint32 $tokenAmtScaled
uint24 $priceLowScaled
uint24 $priceHighScaled
orderModify 0xa0eefff0
uint256 $marketIsBuy
uint32 newTokenAmtScaled
uint24 newPriceLowScaled
uint24 newPriceHighScaled
uint256 orderID
orderTrade 0xc717978f
uint256 $marketIsBuy
uint32 $tokenAmtScaled
uint24 fillPriceWorstScaled
uint256 orderID
vaultDeposit 0x042bbe3a
address token
uint256 amt
vaultWithdraw 0x0fe31eb1
address token
uint256 amt
Recent Transactions
No transactions found for this address