Address Contract Partially Verified
Address
0x287787F55723f7a816aA37De1dbD72a4671De1cc
Balance
0 ETH
Nonce
1
Code Size
15694 bytes
Creator
0x887e5081...87ba at tx 0x4269d91f...96c30b
Indexed Transactions
0
Contract Bytecode
15694 bytes
0x608060405234801561001057600080fd5b50600436106102535760003560e01c80638da5cb5b11610146578063c6a54924116100c3578063d339785011610087578063d339785014610651578063d9c65c2714610664578063de9b771f14610677578063f2fde38b1461068a578063f79e41641461069d578063f953cec7146106b057600080fd5b8063c6a54924146105d9578063c714b768146105ec578063cc581d79146105ff578063cd931e401461062b578063d0b05d351461063e57600080fd5b8063ad280eb01161010a578063ad280eb014610567578063aea4e49e1461057a578063bbb781cc1461058d578063bded9a7c1461059a578063c0857ba0146105c657600080fd5b80638da5cb5b146104f1578063972c492814610502578063998a1d1514610515578063a04b29b914610528578063a6197a9f1461053b57600080fd5b806345f0791d116101d457806370a082311161019857806370a082311461049d578063715018a6146104b0578063795b396d146104b8578063840d6dcf146104cb5780638d18fa62146104de57600080fd5b806345f0791d146104075780634f04eba414610432578063607f2d421461044557806363c28db1146104685780636a6940cc1461048a57600080fd5b80631959a0021161021b5780631959a002146103265780633723148e146103735780633ac4b3ac146103865780633eee69a9146103b25780633f02d59e146103db57600080fd5b806301ffc9a7146102585780630e1db437146102915780630e387de6146102a6578063150b7a02146102db57806315b31bbb14610313575b600080fd5b61027c6102663660046134a9565b6001600160e01b0319166307f5828d60e41b1490565b60405190151581526020015b60405180910390f35b6102a461029f366004613598565b6106c3565b005b6102cd7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b604051908152602001610288565b6102fa6102e9366004613634565b630a85bd0160e11b95945050505050565b6040516001600160e01b03199091168152602001610288565b6102a46103213660046136d2565b6106f8565b6103586103343660046136f4565b60086020526000908152604090206001810154600382015460059092015490919083565b60408051938452602084019290925290820152606001610288565b6102a4610381366004613711565b610722565b6102cd6103943660046136f4565b6001600160a01b031660009081526008602052604090206001015490565b6102cd6103c03660046136f4565b6001600160a01b031660009081526008602052604090205490565b6102cd6103e93660046136f4565b6001600160a01b031660009081526008602052604090206004015490565b60065461041a906001600160a01b031681565b6040516001600160a01b039091168152602001610288565b6102a4610440366004613711565b6108c0565b61027c610453366004613711565b60036020526000908152604090205460ff1681565b61047b6104763660046136f4565b6109ba565b60405161028893929190613765565b60075461041a906001600160a01b031681565b6102cd6104ab3660046136f4565b610b1f565b6102a4610c7b565b6102a46104c63660046137a8565b610cb8565b6102a46104d93660046137a8565b610e2f565b6102a46104ec3660046137a8565b610f7a565b6004546001600160a01b031661041a565b60025461041a906001600160a01b031681565b6102a4610523366004613711565b6110c5565b6102a46105363660046137a8565b611220565b6102cd6105493660046136f4565b6001600160a01b031660009081526008602052604090206002015490565b6102a46105753660046137a8565b6113e5565b6102a46105883660046136f4565b61157b565b60095461027c9060ff1681565b6102cd6105a83660046136f4565b6001600160a01b031660009081526008602052604090206005015490565b60015461041a906001600160a01b031681565b6102a46105e7366004613711565b611609565b6102a46105fa366004613711565b6116da565b6102cd61060d3660046136f4565b6001600160a01b031660009081526008602052604090206003015490565b6102a46106393660046137dc565b611834565b6102a461064c3660046137a8565b611879565b6102a461065f366004613598565b611a11565b6102a4610672366004613711565b611a41565b60005461041a906001600160a01b031681565b6102a46106983660046136f4565b611b0e565b60055461041a906001600160a01b031681565b6102a46106be36600461383c565b611b5b565b8251156106d3576106d3836113e5565b8151156106e3576106e382611879565b8051156106f3576106f381611220565b505050565b6004546001600160a01b0316331461070f57600080fd5b6009805460ff1916911515919091179055565b60095460ff161561074e5760405162461bcd60e51b8152600401610745906138bb565b60405180910390fd5b33600090815260086020908152604091829020805483518184028101840190945280845290926107b692909184918301828280156107ab57602002820191906000526020600020905b815481526020019060010190808311610797575b505050505083611b66565b6107f75760405162461bcd60e51b81526020600482015260126024820152712737ba10323ab733b2b7b71037bbb732b91760711b6044820152606401610745565b6005546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061082b903090339087906004016138f2565b600060405180830381600087803b15801561084557600080fd5b505af1158015610859573d6000803e3d6000fd5b505050506108678183611bbb565b805460000361087857600060018201555b6108bc3360005b604080516001600160a01b039093166020840152820152600160608201526000608082015260a0015b604051602081830303815290604052611ced565b5050565b60095460ff16156108e35760405162461bcd60e51b8152600401610745906138bb565b336000818152600860209081526040808320600480820180546001810182559086529390942090920185905560075490516323b872dd60e01b815291936001600160a01b03909116926323b872dd92610941929130918891016138f2565b600060405180830381600087803b15801561095b57600080fd5b505af115801561096f573d6000803e3d6000fd5b505050508060050154600003610986574260058201555b6108bc3360025b604080516001600160a01b039093166020840152820152600160608201819052608082015260a0016108a8565b6001600160a01b03811660009081526008602090815260408083208151815460e09481028201850190935260c081018381526060958695869591949284929091849190840182828015610a2c57602002820191906000526020600020905b815481526020019060010190808311610a18575b505050505081526020016001820154815260200160028201805480602002602001604051908101604052809291908181526020018280548015610a8e57602002820191906000526020600020905b815481526020019060010190808311610a7a575b505050505081526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015610af057602002820191906000526020600020905b815481526020019060010190808311610adc575b505050918352505060059190910154602090910152805160408201516080909201519097919650945092505050565b6001600160a01b03811660009081526008602052604081205481108015610b5f57506001600160a01b038216600090815260086020526040812060020154115b8015610b8457506001600160a01b038216600090815260086020526040812060040154115b15610b9157506003919050565b6001600160a01b038216600090815260086020526040812054118015610bd057506001600160a01b038216600090815260086020526040812060020154115b8015610bf557506001600160a01b038216600090815260086020526040902060040154155b15610c0257506002919050565b6001600160a01b038216600090815260086020526040812054118015610c4157506001600160a01b038216600090815260086020526040902060020154155b8015610c6657506001600160a01b038216600090815260086020526040902060040154155b15610c7357506001919050565b506000919050565b6004546001600160a01b03163314610ca6576040516330cd747160e01b815260040160405180910390fd5b600480546001600160a01b0319169055565b60095460ff1615610cdb5760405162461bcd60e51b815260040161074590613916565b6000815111610cfc5760405162461bcd60e51b81526004016107459061394d565b3360009081526008602052604081206005810154909103610d1e574260058201555b60005b8251811015610df75781600401838281518110610d4057610d4061397c565b6020908102919091018101518254600181018455600093845291909220015560075483516001600160a01b03909116906323b872dd9033903090879086908110610d8c57610d8c61397c565b60200260200101516040518463ffffffff1660e01b8152600401610db2939291906138f2565b600060405180830381600087803b158015610dcc57600080fd5b505af1158015610de0573d6000803e3d6000fd5b505050508080610def906139a8565b915050610d21565b506108bc3360025b8451604080516001600160a01b03909416602085015283019190915260608201526001608082015260a0016108a8565b60095460ff1615610e525760405162461bcd60e51b815260040161074590613916565b6000815111610e735760405162461bcd60e51b81526004016107459061394d565b3360009081526008602052604081206003810154909103610e95574260038201555b60005b8251811015610f6e5781600201838281518110610eb757610eb761397c565b6020908102919091018101518254600181018455600093845291909220015560065483516001600160a01b03909116906323b872dd9033903090879086908110610f0357610f0361397c565b60200260200101516040518463ffffffff1660e01b8152600401610f29939291906138f2565b600060405180830381600087803b158015610f4357600080fd5b505af1158015610f57573d6000803e3d6000fd5b505050508080610f66906139a8565b915050610e98565b506108bc336001610dff565b60095460ff1615610f9d5760405162461bcd60e51b815260040161074590613916565b6000815111610fbe5760405162461bcd60e51b81526004016107459061394d565b3360009081526008602052604081206001810154909103610fe0574260018201555b60005b82518110156110b957816000018382815181106110025761100261397c565b6020908102919091018101518254600181018455600093845291909220015560055483516001600160a01b03909116906323b872dd903390309087908690811061104e5761104e61397c565b60200260200101516040518463ffffffff1660e01b8152600401611074939291906138f2565b600060405180830381600087803b15801561108e57600080fd5b505af11580156110a2573d6000803e3d6000fd5b5050505080806110b1906139a8565b915050610fe3565b506108bc336000610dff565b60095460ff16156110e85760405162461bcd60e51b8152600401610745906138bb565b336000908152600860209081526040918290206002810180548451818502810185019095528085529193611151939092908301828280156107ab576020028201919060005260206000209081548152602001906001019080831161079757505050505083611b66565b6111915760405162461bcd60e51b81526020600482015260116024820152702737ba1030bb30ba30b91037bbb732b91760791b6044820152606401610745565b6006546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906111c5903090339087906004016138f2565b600060405180830381600087803b1580156111df57600080fd5b505af11580156111f3573d6000803e3d6000fd5b505050506112018183611d58565b600281015460000361121557600060038201555b6108bc33600161087f565b60095460ff16156112435760405162461bcd60e51b8152600401610745906138bb565b336000908152600860205260408120905b82518110156113995760008382815181106112715761127161397c565b602002602001015190506112d7836004018054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020905b8154815260200190600101908083116112b8575b505050505082611b66565b6113165760405162461bcd60e51b815260206004820152601060248201526f2737ba1038bab2b9ba1037bbb732b91760811b6044820152606401610745565b6007546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061134a903090339086906004016138f2565b600060405180830381600087803b15801561136457600080fd5b505af1158015611378573d6000803e3d6000fd5b505050506113868382611e72565b5080611391816139a8565b915050611254565b5060048101546000036113ae57600060058201555b6108bc3360025b8451604080516001600160a01b03909416602085015283019190915260608201526000608082015260a0016108a8565b60095460ff16156114085760405162461bcd60e51b8152600401610745906138bb565b336000908152600860205260408120905b825181101561155e5760008382815181106114365761143661397c565b6020026020010151905061149a836000018054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b857505050505082611b66565b6114db5760405162461bcd60e51b81526020600482015260126024820152712737ba10323ab733b2b7b71037bbb732b91760711b6044820152606401610745565b6005546040516323b872dd60e01b81526001600160a01b03909116906323b872dd9061150f903090339086906004016138f2565b600060405180830381600087803b15801561152957600080fd5b505af115801561153d573d6000803e3d6000fd5b5050505061154b8382611bbb565b5080611556816139a8565b915050611419565b50805460000361157057600060018201555b6108bc3360006113b5565b6002546001600160a01b0316156115e75760405162461bcd60e51b815260206004820152602a60248201527f467842617365526f6f7454756e6e656c3a204348494c445f54554e4e454c5f4160448201526913149150511657d4d15560b21b6064820152608401610745565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b60095460ff161561162c5760405162461bcd60e51b8152600401610745906138bb565b3360008181526008602090815260408083206002810180546001810182559085529290932090910184905560065490516323b872dd60e01b815291926001600160a01b03909116916323b872dd9161168a91309087906004016138f2565b600060405180830381600087803b1580156116a457600080fd5b505af11580156116b8573d6000803e3d6000fd5b5050505080600301546000036116cf574260038201555b6108bc33600161098d565b60095460ff16156116fd5760405162461bcd60e51b8152600401610745906138bb565b336000908152600860209081526040918290206004810180548451818502810185019095528085529193611766939092908301828280156107ab576020028201919060005260206000209081548152602001906001019080831161079757505050505083611b66565b6117a55760405162461bcd60e51b815260206004820152601060248201526f2737ba1038bab2b9ba1037bbb732b91760811b6044820152606401610745565b6007546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906117d9903090339087906004016138f2565b600060405180830381600087803b1580156117f357600080fd5b505af1158015611807573d6000803e3d6000fd5b505050506118158183611e72565b600481015460000361182957600060058201555b6108bc33600261087f565b6004546001600160a01b0316331461184b57600080fd5b600680546001600160a01b039384166001600160a01b03199182161790915560078054929093169116179055565b60095460ff161561189c5760405162461bcd60e51b8152600401610745906138bb565b336000908152600860205260408120905b82518110156119f15760008382815181106118ca576118ca61397c565b6020026020010151905061192e836002018054806020026020016040519081016040528092919081815260200182805480156112cc57602002820191906000526020600020908154815260200190600101908083116112b857505050505082611b66565b61196e5760405162461bcd60e51b81526020600482015260116024820152702737ba1030bb30ba30b91037bbb732b91760791b6044820152606401610745565b6006546040516323b872dd60e01b81526001600160a01b03909116906323b872dd906119a2903090339086906004016138f2565b600060405180830381600087803b1580156119bc57600080fd5b505af11580156119d0573d6000803e3d6000fd5b505050506119de8382611d58565b50806119e9816139a8565b9150506118ad565b506002810154600003611a0657600060038201555b6108bc3360016113b5565b825115611a2157611a2183610f7a565b815115611a3157611a3182610e2f565b8051156106f3576106f381610cb8565b60095460ff1615611a645760405162461bcd60e51b8152600401610745906138bb565b33600081815260086020908152604080832080546001810182558185529290932090910184905560055490516323b872dd60e01b815291926001600160a01b03909116916323b872dd91611abe91309087906004016138f2565b600060405180830381600087803b158015611ad857600080fd5b505af1158015611aec573d6000803e3d6000fd5b505050508060010154600003611b03574260018201555b6108bc33600061098d565b6004546001600160a01b03163314611b39576040516330cd747160e01b815260040160405180910390fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b60006106f382611f8c565b6000805b8351811015611baf5782848281518110611b8657611b8661397c565b602002602001015103611b9d576001915050611bb5565b80611ba7816139a8565b915050611b6a565b50600090505b92915050565b600082600001805480602002602001604051908101604052809291908181526020018280548015611c0b57602002820191906000526020600020905b815481526020019060010190808311611bf7575b505050505090506000805b8251811015611c555783838281518110611c3257611c3261397c565b602002602001015103611c43578091505b80611c4d816139a8565b915050611c16565b5082828281518110611c6957611c6961397c565b602002602001015103611ce75783548290611c86906001906139c1565b81518110611c9657611c9661397c565b6020026020010151846000018281548110611cb357611cb361397c565b6000918252602090912001558354849080611cd057611cd06139d8565b600190038181906000526020600020016000905590555b50505050565b60005460025460405163b472047760e01b81526001600160a01b039283169263b472047792611d23929116908590600401613a1a565b600060405180830381600087803b158015611d3d57600080fd5b505af1158015611d51573d6000803e3d6000fd5b5050505050565b600082600201805480602002602001604051908101604052809291908181526020018280548015611da857602002820191906000526020600020905b815481526020019060010190808311611d94575b505050505090506000805b8251811015611df25783838281518110611dcf57611dcf61397c565b602002602001015103611de0578091505b80611dea816139a8565b915050611db3565b5082828281518110611e0657611e0661397c565b602002602001015103611ce75760028401548290611e26906001906139c1565b81518110611e3657611e3661397c565b6020026020010151846002018281548110611e5357611e5361397c565b60009182526020909120015560028401805480611cd057611cd06139d8565b600082600401805480602002602001604051908101604052809291908181526020018280548015611ec257602002820191906000526020600020905b815481526020019060010190808311611eae575b505050505090506000805b8251811015611f0c5783838281518110611ee957611ee961397c565b602002602001015103611efa578091505b80611f04816139a8565b915050611ecd565b5082828281518110611f2057611f2061397c565b602002602001015103611ce75760048401548290611f40906001906139c1565b81518110611f5057611f5061397c565b6020026020010151846004018281548110611f6d57611f6d61397c565b60009182526020909120015560048401805480611cd057611cd06139d8565b60606000611f9983612275565b90506000611fa6826122d4565b90506000611fb3836122fd565b9050600081611fc184612326565b611fca866124e2565b604051602001611fdc93929190613a5c565b60408051601f1981840301815291815281516020928301206000818152600390935291205490915060ff16156120605760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201526314d4d15160e21b6064820152608401610745565b6000818152600360205260408120805460ff19166001179055612082856124fe565b9050600061208f82612647565b905061209a816126d7565b6002546001600160a01b039081169116146121055760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f54604482015264155393915360da1b6064820152608401610745565b600061211087612700565b9050612130612120846020015190565b8761212a8a61271c565b84612738565b6121885760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201526227a7a360e91b6064820152608401610745565b6121b685612195896129eb565b61219e8a612a07565b846121a88c612a23565b6121b18d612a3f565b612a5b565b5060006121c283612b81565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366121f86121f3836000612bbd565b612bf5565b146122455760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610745565b600061225084612c70565b8060200190518101906122639190613a89565b9b9a5050505050505050505050565b50565b60408051602081019091526060815260006122bf6122ba8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b612c8c565b60408051602081019091529081529392505050565b6060611bb582600001516008815181106122f0576122f061397c565b6020026020010151612da1565b6000611bb582600001516002815181106123195761231961397c565b6020026020010151612bf5565b60408051602081019091526000815281516060919015611bb55760008061234e600086612e3d565b60f81c9050600181148061236557508060ff166003145b1561240c5760018551600261237a9190613aff565b61238491906139c1565b6001600160401b0381111561239b5761239b6134d3565b6040519080825280601f01601f1916602001820160405280156123c5576020820181803683370190505b50925060006123d5600187612e3d565b905080846000815181106123eb576123eb61397c565b60200101906001600160f81b031916908160001a905350600192505061246f565b60028551600261241c9190613aff565b61242691906139c1565b6001600160401b0381111561243d5761243d6134d3565b6040519080825280601f01601f191660200182016040528015612467576020820181803683370190505b509250600091505b60ff82165b83518110156124d95761249e61248d60ff8516836139c1565b612498906002613b1e565b87612e3d565b8482815181106124b0576124b061397c565b60200101906001600160f81b031916908160001a905350806124d1816139a8565b915050612474565b50505092915050565b6000611bb582600001516009815181106123195761231961397c565b61252260405180606001604052806060815260200160608152602001600081525090565b61253c82600001516006815181106122f0576122f061397c565b60208281018290526040805180820182526000808252908301528051808201909152825181529181019082015261257281612ebe565b156125875761258081612c8c565b8252612633565b6020820151805160009061259d906001906139c1565b6001600160401b038111156125b4576125b46134d3565b6040519080825280601f01601f1916602001820160405280156125de576020820181803683370190505b5090506000808360210191508260200190506125fc82828551612ef9565b60408051808201825260008082526020918201528151808301909252845182528085019082015261262c90612c8c565b8652505050505b61263c836124e2565b604083015250919050565b60408051608081018252600091810182815260608083019390935281526020810191909152600061269583600001516003815181106126885761268861397c565b6020026020010151612c8c565b8360400151815181106126aa576126aa61397c565b6020026020010151905060405180604001604052808281526020016126ce83612c8c565b90529392505050565b6000611bb582602001516000815181106126f3576126f361397c565b6020026020010151612f77565b6000611bb582600001516005815181106123195761231961397c565b6060611bb582600001516007815181106122f0576122f061397c565b60008061276c8460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b9050600061277982612c8c565b90506060808560008061278b8b612326565b905080516000036127a65760009750505050505050506129e3565b60005b86518110156129da5781518311156127cc576000985050505050505050506129e3565b6127ee8782815181106127e1576127e161397c565b6020026020010151612f91565b95508580519060200120841461280f576000985050505050505050506129e3565b6128248782815181106126885761268861397c565b945084516011036128f65781518303612883578c80519060200120612855866010815181106122f0576122f061397c565b8051906020012003612872576001985050505050505050506129e3565b6000985050505050505050506129e3565b60008284815181106128975761289761397c565b016020015160f81c905060108111156128bc57600099505050505050505050506129e3565b6128e1868260ff16815181106128d4576128d461397c565b602002602001015161300f565b94506128ee600185613b1e565b9350506129c8565b845160020361287257600061292161291a876000815181106122f0576122f061397c565b848661303d565b83519091506129308286613b1e565b03612983578d80519060200120612953876001815181106122f0576122f061397c565b805190602001200361297157600199505050505050505050506129e3565b600099505050505050505050506129e3565b8060000361299d57600099505050505050505050506129e3565b6129a78185613b1e565b93506129bf866001815181106128d4576128d461397c565b94506129c89050565b806129d2816139a8565b9150506127a9565b50505050505050505b949350505050565b6000611bb582600001516003815181106123195761231961397c565b6000611bb582600001516004815181106123195761231961397c565b6000611bb582600001516000815181106123195761231961397c565b6060611bb582600001516001815181106122f0576122f061397c565b6001546040516320a9cea560e11b8152600481018490526000918291829182916001600160a01b03909116906341539d4a9060240160a060405180830381865afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613b36565b5093505092509250612b28828b612ae891906139c1565b6040805160208082018f90528183018e9052606082018d905260808083018d90528351808403909101815260a09092019092528051910120908588613144565b612b745760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610745565b9998505050505050505050565b6040805160208101909152606081526040518060200160405280612bb584602001516001815181106126885761268861397c565b905292915050565b60408051808201909152600080825260208201528251805183908110612be557612be561397c565b6020026020010151905092915050565b805160009015801590612c0a57508151602110155b612c1357600080fd5b6000612c2283602001516132ac565b90506000818460000151612c3691906139c1565b9050600080838660200151612c4b9190613b1e565b9050805191506020831015612c6757826020036101000a820491505b50949350505050565b6060611bb582602001516002815181106122f0576122f061397c565b6060612c9782612ebe565b612ca057600080fd5b6000612cab8361332e565b90506000816001600160401b03811115612cc757612cc76134d3565b604051908082528060200260200182016040528015612d0c57816020015b6040805180820190915260008082526020820152815260200190600190039081612ce55790505b5090506000612d1e85602001516132ac565b8560200151612d2d9190613b1e565b90506000805b84811015612d9657612d44836133b3565b9150604051806040016040528083815260200184815250848281518110612d6d57612d6d61397c565b6020908102919091010152612d828284613b1e565b925080612d8e816139a8565b915050612d33565b509195945050505050565b8051606090612daf57600080fd5b6000612dbe83602001516132ac565b90506000818460000151612dd291906139c1565b90506000816001600160401b03811115612dee57612dee6134d3565b6040519080825280601f01601f191660200182016040528015612e18576020820181803683370190505b5090506000816020019050612c67848760200151612e369190613b1e565b8285613457565b6000612e4a600284613b99565b15612e8457601082612e5d600286613bad565b81518110612e6d57612e6d61397c565b0160200151612e7f919060f81c613bc1565b612eb4565b601082612e92600286613bad565b81518110612ea257612ea261397c565b0160200151612eb4919060f81c613be3565b60f81b9392505050565b80516000908103612ed157506000919050565b6020820151805160001a9060c0821015612eef575060009392505050565b5060019392505050565b80600003612f0657505050565b60208110612f3e5782518252612f1d602084613b1e565b9250612f2a602083613b1e565b9150612f376020826139c1565b9050612f06565b60006001612f4d8360206139c1565b612f5990610100613ce9565b612f6391906139c1565b935183518516941916939093179091525050565b8051600090601514612f8857600080fd5b611bb582612bf5565b6060600082600001516001600160401b03811115612fb157612fb16134d3565b6040519080825280601f01601f191660200182016040528015612fdb576020820181803683370190505b5090508051600003612fed5792915050565b60008160200190506130088460200151828660000151613457565b5092915050565b805160009060211461302057600080fd5b600080836020015160016130349190613b1e565b51949350505050565b6000808061304a86612326565b9050600081516001600160401b03811115613067576130676134d3565b6040519080825280601f01601f191660200182016040528015613091576020820181803683370190505b509050845b82516130a29087613b1e565b8110156131155760008782815181106130bd576130bd61397c565b01602001516001600160f81b031916905080836130da89856139c1565b815181106130ea576130ea61397c565b60200101906001600160f81b031916908160001a90535050808061310d906139a8565b915050613096565b5080805190602001208280519060200120036131345781519250613139565b600092505b509095945050505050565b6000602082516131549190613b99565b156131985760405162461bcd60e51b8152602060048201526014602482015273092dcecc2d8d2c840e0e4dedecc40d8cadccee8d60631b6044820152606401610745565b6000602083516131a89190613bad565b90506131b5816002613ce9565b85106131fb5760405162461bcd60e51b81526020600482015260156024820152744c65616620696e64657820697320746f6f2062696760581b6044820152606401610745565b60008660205b8551811161329e5785810151925061321a600289613b99565b60000361325257604080516020810184905290810184905260600160405160208183030381529060405280519060200120915061327f565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b61328a600289613bad565b9750613297602082613b1e565b9050613201565b509094149695505050505050565b8051600090811a60808110156132c55750600092915050565b60b88110806132e0575060c081108015906132e0575060f881105b156132ee5750600192915050565b60c081101561332257613303600160b8613cf5565b6133109060ff16826139c1565b61331b906001613b1e565b9392505050565b613303600160f8613cf5565b8051600090810361334157506000919050565b60008061335184602001516132ac565b84602001516133609190613b1e565b90506000846000015185602001516133789190613b1e565b90505b808210156133aa5761338c826133b3565b6133969083613b1e565b9150826133a2816139a8565b93505061337b565b50909392505050565b80516000908190811a60808110156133ce5760019150613008565b60b88110156133f4576133e26080826139c1565b6133ed906001613b1e565b9150613008565b60c08110156134215760b78103600185019450806020036101000a85510460018201810193505050613008565b60f8811015613435576133e260c0826139c1565b60019390930151602084900360f7016101000a900490920160f5190192915050565b8060000361346457505050565b6020811061349c578251825261347b602084613b1e565b9250613488602083613b1e565b91506134956020826139c1565b9050613464565b80600003612f3e57505050565b6000602082840312156134bb57600080fd5b81356001600160e01b03198116811461331b57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613511576135116134d3565b604052919050565b600082601f83011261352a57600080fd5b813560206001600160401b03821115613545576135456134d3565b8160051b6135548282016134e9565b928352848101820192828101908785111561356e57600080fd5b83870192505b8483101561358d57823582529183019190830190613574565b979650505050505050565b6000806000606084860312156135ad57600080fd5b83356001600160401b03808211156135c457600080fd5b6135d087838801613519565b945060208601359150808211156135e657600080fd5b6135f287838801613519565b9350604086013591508082111561360857600080fd5b5061361586828701613519565b9150509250925092565b6001600160a01b038116811461227257600080fd5b60008060008060006080868803121561364c57600080fd5b85356136578161361f565b945060208601356136678161361f565b93506040860135925060608601356001600160401b038082111561368a57600080fd5b818801915088601f83011261369e57600080fd5b8135818111156136ad57600080fd5b8960208285010111156136bf57600080fd5b9699959850939650602001949392505050565b6000602082840312156136e457600080fd5b8135801515811461331b57600080fd5b60006020828403121561370657600080fd5b813561331b8161361f565b60006020828403121561372357600080fd5b5035919050565b600081518084526020808501945080840160005b8381101561375a5781518752958201959082019060010161373e565b509495945050505050565b606081526000613778606083018661372a565b828103602084015261378a818661372a565b9050828103604084015261379e818561372a565b9695505050505050565b6000602082840312156137ba57600080fd5b81356001600160401b038111156137d057600080fd5b6129e384828501613519565b600080604083850312156137ef57600080fd5b82356137fa8161361f565b9150602083013561380a8161361f565b809150509250929050565b60006001600160401b0382111561382e5761382e6134d3565b50601f01601f191660200190565b60006020828403121561384e57600080fd5b81356001600160401b0381111561386457600080fd5b8201601f8101841361387557600080fd5b803561388861388382613815565b6134e9565b81815285602083850101111561389d57600080fd5b81602084016020830137600091810160200191909152949350505050565b6020808252601c908201527f5374616b696e672069732063757272656e746c79207061757365642e00000000604082015260600190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b60208082526019908201527f5374616b696e672063757272656e746c79207061757365642e00000000000000604082015260600190565b6020808252601590820152742737903a37b5b2b724b23990383937bb34b232b21760591b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016139ba576139ba613992565b5060010190565b6000828210156139d3576139d3613992565b500390565b634e487b7160e01b600052603160045260246000fd5b60005b83811015613a095781810151838201526020016139f1565b83811115611ce75750506000910152565b60018060a01b03831681526040602082015260008251806040840152613a478160608501602087016139ee565b601f01601f1916919091016060019392505050565b83815260008351613a748160208501602088016139ee565b60209201918201929092526040019392505050565b600060208284031215613a9b57600080fd5b81516001600160401b03811115613ab157600080fd5b8201601f81018413613ac257600080fd5b8051613ad061388382613815565b818152856020838501011115613ae557600080fd5b613af68260208301602086016139ee565b95945050505050565b6000816000190483118215151615613b1957613b19613992565b500290565b60008219821115613b3157613b31613992565b500190565b600080600080600060a08688031215613b4e57600080fd5b855194506020860151935060408601519250606086015191506080860151613b758161361f565b809150509295509295909350565b634e487b7160e01b600052601260045260246000fd5b600082613ba857613ba8613b83565b500690565b600082613bbc57613bbc613b83565b500490565b600060ff831680613bd457613bd4613b83565b8060ff84160691505092915050565b600060ff831680613bf657613bf6613b83565b8060ff84160491505092915050565b600181815b80851115613c40578160001904821115613c2657613c26613992565b80851615613c3357918102915b93841c9390800290613c0a565b509250929050565b600082613c5757506001611bb5565b81613c6457506000611bb5565b8160018114613c7a5760028114613c8457613ca0565b6001915050611bb5565b60ff841115613c9557613c95613992565b50506001821b611bb5565b5060208310610133831016604e8410600b8410161715613cc3575081810a611bb5565b613ccd8383613c05565b8060001904821115613ce157613ce1613992565b029392505050565b600061331b8383613c48565b600060ff821660ff841680821015613d0f57613d0f613992565b9003939250505056fea26469706673582212208e0052f2db19d7a445185f864f84206c0a7108e7286ea9dacdc8eeafcaef33fd64736f6c634300080d0033
Verified Source Code Partial Match
Compiler: v0.8.13+commit.abaa5c0e
EVM: london
Optimization: Yes (200 runs)
DungeonRewards.sol 1725 lines
// File: default_workspace/contracts/Ownable.sol
pragma solidity ^0.8.10;
error NotOwner();
// https://github.com/m1guelpf/erc721-drop/blob/main/src/LilOwnable.sol
abstract contract Ownable {
address internal _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
modifier onlyOwner() {
require(_owner == msg.sender);
_;
}
constructor() {
_owner = msg.sender;
}
function owner() external view returns (address) {
return _owner;
}
function transferOwnership(address _newOwner) external {
if (msg.sender != _owner) revert NotOwner();
_owner = _newOwner;
}
function renounceOwnership() public {
if (msg.sender != _owner) revert NotOwner();
_owner = address(0);
}
function supportsInterface(bytes4 interfaceId)
public
pure
virtual
returns (bool)
{
return interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173
}
}
// File: default_workspace/contracts/lib/Merkle.sol
pragma solidity ^0.8.0;
library Merkle {
function checkMembership(
bytes32 leaf,
uint256 index,
bytes32 rootHash,
bytes memory proof
) internal pure returns (bool) {
require(proof.length % 32 == 0, "Invalid proof length");
uint256 proofHeight = proof.length / 32;
// Proof of size n means, height of the tree is n+1.
// In a tree of height n+1, max #leafs possible is 2 ^ n
require(index < 2**proofHeight, "Leaf index is too big");
bytes32 proofElement;
bytes32 computedHash = leaf;
for (uint256 i = 32; i <= proof.length; i += 32) {
assembly {
proofElement := mload(add(proof, i))
}
if (index % 2 == 0) {
computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
} else {
computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
}
index = index / 2;
}
return computedHash == rootHash;
}
}
// File: default_workspace/contracts/lib/RLPReader.sol
/*
* @author Hamdi Allam [email protected]
* Please reach out with any questions or concerns
*/
pragma solidity ^0.8.0;
library RLPReader {
uint8 constant STRING_SHORT_START = 0x80;
uint8 constant STRING_LONG_START = 0xb8;
uint8 constant LIST_SHORT_START = 0xc0;
uint8 constant LIST_LONG_START = 0xf8;
uint8 constant WORD_SIZE = 32;
struct RLPItem {
uint256 len;
uint256 memPtr;
}
struct Iterator {
RLPItem item; // Item that's being iterated over.
uint256 nextPtr; // Position of the next item in the list.
}
/*
* @dev Returns the next element in the iteration. Reverts if it has not next element.
* @param self The iterator.
* @return The next element in the iteration.
*/
function next(Iterator memory self) internal pure returns (RLPItem memory) {
require(hasNext(self));
uint256 ptr = self.nextPtr;
uint256 itemLength = _itemLength(ptr);
self.nextPtr = ptr + itemLength;
return RLPItem(itemLength, ptr);
}
/*
* @dev Returns true if the iteration has more elements.
* @param self The iterator.
* @return true if the iteration has more elements.
*/
function hasNext(Iterator memory self) internal pure returns (bool) {
RLPItem memory item = self.item;
return self.nextPtr < item.memPtr + item.len;
}
/*
* @param item RLP encoded bytes
*/
function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) {
uint256 memPtr;
assembly {
memPtr := add(item, 0x20)
}
return RLPItem(item.length, memPtr);
}
/*
* @dev Create an iterator. Reverts if item is not a list.
* @param self The RLP item.
* @return An 'Iterator' over the item.
*/
function iterator(RLPItem memory self) internal pure returns (Iterator memory) {
require(isList(self));
uint256 ptr = self.memPtr + _payloadOffset(self.memPtr);
return Iterator(self, ptr);
}
/*
* @param item RLP encoded bytes
*/
function rlpLen(RLPItem memory item) internal pure returns (uint256) {
return item.len;
}
/*
* @param item RLP encoded bytes
*/
function payloadLen(RLPItem memory item) internal pure returns (uint256) {
return item.len - _payloadOffset(item.memPtr);
}
/*
* @param item RLP encoded list in bytes
*/
function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) {
require(isList(item));
uint256 items = numItems(item);
RLPItem[] memory result = new RLPItem[](items);
uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr);
uint256 dataLen;
for (uint256 i = 0; i < items; i++) {
dataLen = _itemLength(memPtr);
result[i] = RLPItem(dataLen, memPtr);
memPtr = memPtr + dataLen;
}
return result;
}
// @return indicator whether encoded payload is a list. negate this function call for isData.
function isList(RLPItem memory item) internal pure returns (bool) {
if (item.len == 0) return false;
uint8 byte0;
uint256 memPtr = item.memPtr;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < LIST_SHORT_START) return false;
return true;
}
/*
* @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory.
* @return keccak256 hash of RLP encoded bytes.
*/
function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) {
uint256 ptr = item.memPtr;
uint256 len = item.len;
bytes32 result;
assembly {
result := keccak256(ptr, len)
}
return result;
}
function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) {
uint256 offset = _payloadOffset(item.memPtr);
uint256 memPtr = item.memPtr + offset;
uint256 len = item.len - offset; // data length
return (memPtr, len);
}
/*
* @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory.
* @return keccak256 hash of the item payload.
*/
function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) {
(uint256 memPtr, uint256 len) = payloadLocation(item);
bytes32 result;
assembly {
result := keccak256(memPtr, len)
}
return result;
}
/** RLPItem conversions into data types **/
// @returns raw rlp encoding in bytes
function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) {
bytes memory result = new bytes(item.len);
if (result.length == 0) return result;
uint256 ptr;
assembly {
ptr := add(0x20, result)
}
copy(item.memPtr, ptr, item.len);
return result;
}
// any non-zero byte is considered true
function toBoolean(RLPItem memory item) internal pure returns (bool) {
require(item.len == 1);
uint256 result;
uint256 memPtr = item.memPtr;
assembly {
result := byte(0, mload(memPtr))
}
return result == 0 ? false : true;
}
function toAddress(RLPItem memory item) internal pure returns (address) {
// 1 byte for the length prefix
require(item.len == 21);
return address(uint160(toUint(item)));
}
function toUint(RLPItem memory item) internal pure returns (uint256) {
require(item.len > 0 && item.len <= 33);
uint256 offset = _payloadOffset(item.memPtr);
uint256 len = item.len - offset;
uint256 result;
uint256 memPtr = item.memPtr + offset;
assembly {
result := mload(memPtr)
// shfit to the correct location if neccesary
if lt(len, 32) {
result := div(result, exp(256, sub(32, len)))
}
}
return result;
}
// enforces 32 byte length
function toUintStrict(RLPItem memory item) internal pure returns (uint256) {
// one byte prefix
require(item.len == 33);
uint256 result;
uint256 memPtr = item.memPtr + 1;
assembly {
result := mload(memPtr)
}
return result;
}
function toBytes(RLPItem memory item) internal pure returns (bytes memory) {
require(item.len > 0);
uint256 offset = _payloadOffset(item.memPtr);
uint256 len = item.len - offset; // data length
bytes memory result = new bytes(len);
uint256 destPtr;
assembly {
destPtr := add(0x20, result)
}
copy(item.memPtr + offset, destPtr, len);
return result;
}
/*
* Private Helpers
*/
// @return number of payload items inside an encoded list.
function numItems(RLPItem memory item) private pure returns (uint256) {
if (item.len == 0) return 0;
uint256 count = 0;
uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr);
uint256 endPtr = item.memPtr + item.len;
while (currPtr < endPtr) {
currPtr = currPtr + _itemLength(currPtr); // skip over an item
count++;
}
return count;
}
// @return entire rlp item byte length
function _itemLength(uint256 memPtr) private pure returns (uint256) {
uint256 itemLen;
uint256 byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START) itemLen = 1;
else if (byte0 < STRING_LONG_START) itemLen = byte0 - STRING_SHORT_START + 1;
else if (byte0 < LIST_SHORT_START) {
assembly {
let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is
memPtr := add(memPtr, 1) // skip over the first byte
/* 32 byte word size */
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len
itemLen := add(dataLen, add(byteLen, 1))
}
} else if (byte0 < LIST_LONG_START) {
itemLen = byte0 - LIST_SHORT_START + 1;
} else {
assembly {
let byteLen := sub(byte0, 0xf7)
memPtr := add(memPtr, 1)
let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length
itemLen := add(dataLen, add(byteLen, 1))
}
}
return itemLen;
}
// @return number of bytes until the data
function _payloadOffset(uint256 memPtr) private pure returns (uint256) {
uint256 byte0;
assembly {
byte0 := byte(0, mload(memPtr))
}
if (byte0 < STRING_SHORT_START) return 0;
else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) return 1;
else if (byte0 < LIST_SHORT_START)
// being explicit
return byte0 - (STRING_LONG_START - 1) + 1;
else return byte0 - (LIST_LONG_START - 1) + 1;
}
/*
* @param src Pointer to source
* @param dest Pointer to destination
* @param len Amount of memory to copy from the source
*/
function copy(
uint256 src,
uint256 dest,
uint256 len
) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
if (len == 0) return;
// left over bytes. Mask is used to remove unwanted bytes from the word
uint256 mask = 256**(WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
}
// File: default_workspace/contracts/lib/ExitPayloadReader.sol
pragma solidity ^0.8.0;
library ExitPayloadReader {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;
uint8 constant WORD_SIZE = 32;
struct ExitPayload {
RLPReader.RLPItem[] data;
}
struct Receipt {
RLPReader.RLPItem[] data;
bytes raw;
uint256 logIndex;
}
struct Log {
RLPReader.RLPItem data;
RLPReader.RLPItem[] list;
}
struct LogTopics {
RLPReader.RLPItem[] data;
}
// copy paste of private copy() from RLPReader to avoid changing of existing contracts
function copy(
uint256 src,
uint256 dest,
uint256 len
) private pure {
if (len == 0) return;
// copy as many word sizes as possible
for (; len >= WORD_SIZE; len -= WORD_SIZE) {
assembly {
mstore(dest, mload(src))
}
src += WORD_SIZE;
dest += WORD_SIZE;
}
// left over bytes. Mask is used to remove unwanted bytes from the word
uint256 mask = 256**(WORD_SIZE - len) - 1;
assembly {
let srcpart := and(mload(src), not(mask)) // zero out src
let destpart := and(mload(dest), mask) // retrieve the bytes
mstore(dest, or(destpart, srcpart))
}
}
function toExitPayload(bytes memory data) internal pure returns (ExitPayload memory) {
RLPReader.RLPItem[] memory payloadData = data.toRlpItem().toList();
return ExitPayload(payloadData);
}
function getHeaderNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[0].toUint();
}
function getBlockProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[1].toBytes();
}
function getBlockNumber(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[2].toUint();
}
function getBlockTime(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[3].toUint();
}
function getTxRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[4].toUint());
}
function getReceiptRoot(ExitPayload memory payload) internal pure returns (bytes32) {
return bytes32(payload.data[5].toUint());
}
function getReceipt(ExitPayload memory payload) internal pure returns (Receipt memory receipt) {
receipt.raw = payload.data[6].toBytes();
RLPReader.RLPItem memory receiptItem = receipt.raw.toRlpItem();
if (receiptItem.isList()) {
// legacy tx
receipt.data = receiptItem.toList();
} else {
// pop first byte before parsting receipt
bytes memory typedBytes = receipt.raw;
bytes memory result = new bytes(typedBytes.length - 1);
uint256 srcPtr;
uint256 destPtr;
assembly {
srcPtr := add(33, typedBytes)
destPtr := add(0x20, result)
}
copy(srcPtr, destPtr, result.length);
receipt.data = result.toRlpItem().toList();
}
receipt.logIndex = getReceiptLogIndex(payload);
return receipt;
}
function getReceiptProof(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[7].toBytes();
}
function getBranchMaskAsBytes(ExitPayload memory payload) internal pure returns (bytes memory) {
return payload.data[8].toBytes();
}
function getBranchMaskAsUint(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[8].toUint();
}
function getReceiptLogIndex(ExitPayload memory payload) internal pure returns (uint256) {
return payload.data[9].toUint();
}
// Receipt methods
function toBytes(Receipt memory receipt) internal pure returns (bytes memory) {
return receipt.raw;
}
function getLog(Receipt memory receipt) internal pure returns (Log memory) {
RLPReader.RLPItem memory logData = receipt.data[3].toList()[receipt.logIndex];
return Log(logData, logData.toList());
}
// Log methods
function getEmitter(Log memory log) internal pure returns (address) {
return RLPReader.toAddress(log.list[0]);
}
function getTopics(Log memory log) internal pure returns (LogTopics memory) {
return LogTopics(log.list[1].toList());
}
function getData(Log memory log) internal pure returns (bytes memory) {
return log.list[2].toBytes();
}
function toRlpBytes(Log memory log) internal pure returns (bytes memory) {
return log.data.toRlpBytes();
}
// LogTopics methods
function getField(LogTopics memory topics, uint256 index) internal pure returns (RLPReader.RLPItem memory) {
return topics.data[index];
}
}
// File: default_workspace/contracts/lib/MerklePatriciaProof.sol
pragma solidity ^0.8.0;
library MerklePatriciaProof {
/*
* @dev Verifies a merkle patricia proof.
* @param value The terminating value in the trie.
* @param encodedPath The path in the trie leading to value.
* @param rlpParentNodes The rlp encoded stack of nodes.
* @param root The root hash of the trie.
* @return The boolean validity of the proof.
*/
function verify(
bytes memory value,
bytes memory encodedPath,
bytes memory rlpParentNodes,
bytes32 root
) internal pure returns (bool) {
RLPReader.RLPItem memory item = RLPReader.toRlpItem(rlpParentNodes);
RLPReader.RLPItem[] memory parentNodes = RLPReader.toList(item);
bytes memory currentNode;
RLPReader.RLPItem[] memory currentNodeList;
bytes32 nodeKey = root;
uint256 pathPtr = 0;
bytes memory path = _getNibbleArray(encodedPath);
if (path.length == 0) {
return false;
}
for (uint256 i = 0; i < parentNodes.length; i++) {
if (pathPtr > path.length) {
return false;
}
currentNode = RLPReader.toRlpBytes(parentNodes[i]);
if (nodeKey != keccak256(currentNode)) {
return false;
}
currentNodeList = RLPReader.toList(parentNodes[i]);
if (currentNodeList.length == 17) {
if (pathPtr == path.length) {
if (keccak256(RLPReader.toBytes(currentNodeList[16])) == keccak256(value)) {
return true;
} else {
return false;
}
}
uint8 nextPathNibble = uint8(path[pathPtr]);
if (nextPathNibble > 16) {
return false;
}
nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[nextPathNibble]));
pathPtr += 1;
} else if (currentNodeList.length == 2) {
uint256 traversed = _nibblesToTraverse(RLPReader.toBytes(currentNodeList[0]), path, pathPtr);
if (pathPtr + traversed == path.length) {
//leaf node
if (keccak256(RLPReader.toBytes(currentNodeList[1])) == keccak256(value)) {
return true;
} else {
return false;
}
}
//extension node
if (traversed == 0) {
return false;
}
pathPtr += traversed;
nodeKey = bytes32(RLPReader.toUintStrict(currentNodeList[1]));
} else {
return false;
}
}
}
function _nibblesToTraverse(
bytes memory encodedPartialPath,
bytes memory path,
uint256 pathPtr
) private pure returns (uint256) {
uint256 len = 0;
// encodedPartialPath has elements that are each two hex characters (1 byte), but partialPath
// and slicedPath have elements that are each one hex character (1 nibble)
bytes memory partialPath = _getNibbleArray(encodedPartialPath);
bytes memory slicedPath = new bytes(partialPath.length);
// pathPtr counts nibbles in path
// partialPath.length is a number of nibbles
for (uint256 i = pathPtr; i < pathPtr + partialPath.length; i++) {
bytes1 pathNibble = path[i];
slicedPath[i - pathPtr] = pathNibble;
}
if (keccak256(partialPath) == keccak256(slicedPath)) {
len = partialPath.length;
} else {
len = 0;
}
return len;
}
// bytes b must be hp encoded
function _getNibbleArray(bytes memory b) internal pure returns (bytes memory) {
bytes memory nibbles = "";
if (b.length > 0) {
uint8 offset;
uint8 hpNibble = uint8(_getNthNibbleOfBytes(0, b));
if (hpNibble == 1 || hpNibble == 3) {
nibbles = new bytes(b.length * 2 - 1);
bytes1 oddNibble = _getNthNibbleOfBytes(1, b);
nibbles[0] = oddNibble;
offset = 1;
} else {
nibbles = new bytes(b.length * 2 - 2);
offset = 0;
}
for (uint256 i = offset; i < nibbles.length; i++) {
nibbles[i] = _getNthNibbleOfBytes(i - offset + 2, b);
}
}
return nibbles;
}
function _getNthNibbleOfBytes(uint256 n, bytes memory str) private pure returns (bytes1) {
return bytes1(n % 2 == 0 ? uint8(str[n / 2]) / 0x10 : uint8(str[n / 2]) % 0x10);
}
}
// File: default_workspace/contracts/tunnel/FxBaseRootTunnel.sol
pragma solidity ^0.8.0;
interface IFxStateSender {
function sendMessageToChild(address _receiver, bytes calldata _data) external;
}
contract ICheckpointManager {
struct HeaderBlock {
bytes32 root;
uint256 start;
uint256 end;
uint256 createdAt;
address proposer;
}
/**
* @notice mapping of checkpoint header numbers to block details
* @dev These checkpoints are submited by plasma contracts
*/
mapping(uint256 => HeaderBlock) public headerBlocks;
}
abstract contract FxBaseRootTunnel {
using RLPReader for RLPReader.RLPItem;
using Merkle for bytes32;
using ExitPayloadReader for bytes;
using ExitPayloadReader for ExitPayloadReader.ExitPayload;
using ExitPayloadReader for ExitPayloadReader.Log;
using ExitPayloadReader for ExitPayloadReader.LogTopics;
using ExitPayloadReader for ExitPayloadReader.Receipt;
// keccak256(MessageSent(bytes))
bytes32 public constant SEND_MESSAGE_EVENT_SIG = 0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036;
// state sender contract
IFxStateSender public fxRoot;
// root chain manager
ICheckpointManager public checkpointManager;
// child tunnel contract which receives and sends messages
address public fxChildTunnel;
// storage to avoid duplicate exits
mapping(bytes32 => bool) public processedExits;
constructor(address _checkpointManager, address _fxRoot) {
checkpointManager = ICheckpointManager(_checkpointManager);
fxRoot = IFxStateSender(_fxRoot);
}
// set fxChildTunnel if not set already
function setFxChildTunnel(address _fxChildTunnel) public virtual {
require(fxChildTunnel == address(0x0), "FxBaseRootTunnel: CHILD_TUNNEL_ALREADY_SET");
fxChildTunnel = _fxChildTunnel;
}
/**
* @notice Send bytes message to Child Tunnel
* @param message bytes message that will be sent to Child Tunnel
* some message examples -
* abi.encode(tokenId);
* abi.encode(tokenId, tokenMetadata);
* abi.encode(messageType, messageData);
*/
function _sendMessageToChild(bytes memory message) internal {
fxRoot.sendMessageToChild(fxChildTunnel, message);
}
function _validateAndExtractMessage(bytes memory inputData) internal returns (bytes memory) {
ExitPayloadReader.ExitPayload memory payload = inputData.toExitPayload();
bytes memory branchMaskBytes = payload.getBranchMaskAsBytes();
uint256 blockNumber = payload.getBlockNumber();
// checking if exit has already been processed
// unique exit is identified using hash of (blockNumber, branchMask, receiptLogIndex)
bytes32 exitHash = keccak256(
abi.encodePacked(
blockNumber,
// first 2 nibbles are dropped while generating nibble array
// this allows branch masks that are valid but bypass exitHash check (changing first 2 nibbles only)
// so converting to nibble array and then hashing it
MerklePatriciaProof._getNibbleArray(branchMaskBytes),
payload.getReceiptLogIndex()
)
);
require(processedExits[exitHash] == false, "FxRootTunnel: EXIT_ALREADY_PROCESSED");
processedExits[exitHash] = true;
ExitPayloadReader.Receipt memory receipt = payload.getReceipt();
ExitPayloadReader.Log memory log = receipt.getLog();
// check child tunnel
require(fxChildTunnel == log.getEmitter(), "FxRootTunnel: INVALID_FX_CHILD_TUNNEL");
bytes32 receiptRoot = payload.getReceiptRoot();
// verify receipt inclusion
require(
MerklePatriciaProof.verify(receipt.toBytes(), branchMaskBytes, payload.getReceiptProof(), receiptRoot),
"FxRootTunnel: INVALID_RECEIPT_PROOF"
);
// verify checkpoint inclusion
_checkBlockMembershipInCheckpoint(
blockNumber,
payload.getBlockTime(),
payload.getTxRoot(),
receiptRoot,
payload.getHeaderNumber(),
payload.getBlockProof()
);
ExitPayloadReader.LogTopics memory topics = log.getTopics();
require(
bytes32(topics.getField(0).toUint()) == SEND_MESSAGE_EVENT_SIG, // topic0 is event sig
"FxRootTunnel: INVALID_SIGNATURE"
);
// received message data
bytes memory message = abi.decode(log.getData(), (bytes)); // event decodes params again, so decoding bytes to get message
return message;
}
function _checkBlockMembershipInCheckpoint(
uint256 blockNumber,
uint256 blockTime,
bytes32 txRoot,
bytes32 receiptRoot,
uint256 headerNumber,
bytes memory blockProof
) private view returns (uint256) {
(bytes32 headerRoot, uint256 startBlock, , uint256 createdAt, ) = checkpointManager.headerBlocks(headerNumber);
require(
keccak256(abi.encodePacked(blockNumber, blockTime, txRoot, receiptRoot)).checkMembership(
blockNumber - startBlock,
headerRoot,
blockProof
),
"FxRootTunnel: INVALID_HEADER"
);
return createdAt;
}
/**
* @notice receive message from L2 to L1, validated by proof
* @dev This function verifies if the transaction actually happened on child chain
*
* @param inputData RLP encoded data of the reference tx containing following list of fields
* 0 - headerNumber - Checkpoint header block number containing the reference tx
* 1 - blockProof - Proof that the block header (in the child chain) is a leaf in the submitted merkle root
* 2 - blockNumber - Block number containing the reference tx on child chain
* 3 - blockTime - Reference tx block time
* 4 - txRoot - Transactions root of block
* 5 - receiptRoot - Receipts root of block
* 6 - receipt - Receipt of the reference transaction
* 7 - receiptProof - Merkle proof of the reference receipt
* 8 - branchMask - 32 bits denoting the path of receipt in merkle tree
* 9 - receiptLogIndex - Log Index to read from the receipt
*/
function receiveMessage(bytes memory inputData) public virtual {
bytes memory message = _validateAndExtractMessage(inputData);
_processMessageFromChild(message);
}
/**
* @notice Process message received from Child Tunnel
* @dev function needs to be implemented to handle message as per requirement
* This is called by onStateReceive function.
* Since it is called via a system call, any event will not be emitted during its execution.
* @param message bytes message that was sent from Child Tunnel
*/
function _processMessageFromChild(bytes memory message) internal virtual;
}
// File: default_workspace/contracts/IDungeonRewards.sol
pragma solidity ^0.8.12;
interface IDungeonRewards {
// so we can confirm whether a wallet holds any staked dungeons, useful for Generative Avatars gas-only mint
function balanceOfDungeons(address owner) external view returns (uint256);
// so we can confirm when a wallet staked their dungeons, useful for Generative Avatars gas-only mint
function dungeonFirstStaked(address owner) external view returns (uint256);
function balanceOfAvatars(address owner) external view returns (uint256);
function avatarFirstStaked(address owner) external view returns (uint256);
function balanceOfQuests(address owner) external view returns (uint256);
function questFirstStaked(address owner) external view returns (uint256);
function getStakedTokens(address user) external view returns (uint256[] memory dungeons, uint256[] memory avatars,
uint256[] memory quests);
}
// File: default_workspace/contracts/ERC721.sol
pragma solidity >=0.8.0;
/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
/// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC.
abstract contract ERC721 {
/*///////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
event Transfer(address indexed from, address indexed to, uint256 indexed id);
event Approval(address indexed owner, address indexed spender, uint256 indexed id);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/*///////////////////////////////////////////////////////////////
METADATA STORAGE/LOGIC
//////////////////////////////////////////////////////////////*/
string public name;
string public symbol;
function tokenURI(uint256 id) public view virtual returns (string memory);
/*///////////////////////////////////////////////////////////////
ERC721 STORAGE
//////////////////////////////////////////////////////////////*/
mapping(address => uint256) public balanceOf;
mapping(uint256 => address) public ownerOf;
mapping(uint256 => address) public getApproved;
mapping(address => mapping(address => bool)) public isApprovedForAll;
/*///////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
constructor(string memory _name, string memory _symbol) {
name = _name;
symbol = _symbol;
}
/*///////////////////////////////////////////////////////////////
ERC721 LOGIC
//////////////////////////////////////////////////////////////*/
function approve(address spender, uint256 id) public virtual {
address owner = ownerOf[id];
require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");
getApproved[id] = spender;
emit Approval(owner, spender, id);
}
function setApprovalForAll(address operator, bool approved) public virtual {
isApprovedForAll[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
function transferFrom(
address from,
address to,
uint256 id
) public virtual {
require(from == ownerOf[id], "WRONG_FROM");
require(to != address(0), "INVALID_RECIPIENT");
require(
msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender],
"NOT_AUTHORIZED"
);
// Underflow of the sender's balance is impossible because we check for
// ownership above and the recipient's balance can't realistically overflow.
unchecked {
balanceOf[from]--;
balanceOf[to]++;
}
ownerOf[id] = to;
delete getApproved[id];
emit Transfer(from, to, id);
}
function safeTransferFrom(
address from,
address to,
uint256 id
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function safeTransferFrom(
address from,
address to,
uint256 id,
bytes memory data
) public virtual {
transferFrom(from, to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
/*///////////////////////////////////////////////////////////////
ERC165 LOGIC
//////////////////////////////////////////////////////////////*/
function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) {
return
interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
}
/*///////////////////////////////////////////////////////////////
INTERNAL MINT/BURN LOGIC
//////////////////////////////////////////////////////////////*/
function _mint(address to, uint256 id) internal virtual {
require(to != address(0), "INVALID_RECIPIENT");
require(ownerOf[id] == address(0), "ALREADY_MINTED");
// Counter overflow is incredibly unrealistic.
unchecked {
balanceOf[to]++;
}
ownerOf[id] = to;
emit Transfer(address(0), to, id);
}
function _burn(uint256 id) internal virtual {
address owner = ownerOf[id];
require(ownerOf[id] != address(0), "NOT_MINTED");
// Ownership check above ensures no underflow.
unchecked {
balanceOf[owner]--;
}
delete ownerOf[id];
delete getApproved[id];
emit Transfer(owner, address(0), id);
}
/*///////////////////////////////////////////////////////////////
INTERNAL SAFE MINT LOGIC
//////////////////////////////////////////////////////////////*/
function _safeMint(address to, uint256 id) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
function _safeMint(
address to,
uint256 id,
bytes memory data
) internal virtual {
_mint(to, id);
require(
to.code.length == 0 ||
ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
}
}
/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol)
interface ERC721TokenReceiver {
function onERC721Received(
address operator,
address from,
uint256 id,
bytes calldata data
) external returns (bytes4);
}
// File: default_workspace/contracts/IDNGToken.sol
pragma solidity ^0.8.12;
interface IDNGToken {
enum NftType {
Dungeon,
Avatar,
Quest
}
}
// File: default_workspace/contracts/DungeonRewards.sol
pragma solidity ^0.8.12;
/**
________ ___ ___ ________ ________ _______ ________ ________
|\ ___ \|\ \|\ \|\ ___ \|\ ____\|\ ___ \ |\ __ \|\ ___ \
\ \ \_|\ \ \ \\\ \ \ \\ \ \ \ \___|\ \ __/|\ \ \|\ \ \ \\ \ \
\ \ \ \\ \ \ \\\ \ \ \\ \ \ \ \ __\ \ \_|/_\ \ \\\ \ \ \\ \ \
\ \ \_\\ \ \ \\\ \ \ \\ \ \ \ \|\ \ \ \_|\ \ \ \\\ \ \ \\ \ \
\ \_______\ \_______\ \__\\ \__\ \_______\ \_______\ \_______\ \__\\ \__\
\|_______|\|_______|\|__| \|__|\|_______|\|_______|\|_______|\|__| \|__|
________ _______ ___ __ ________ ________ ________ ________
|\ __ \|\ ___ \ |\ \ |\ \|\ __ \|\ __ \|\ ___ \|\ ____\
\ \ \|\ \ \ __/|\ \ \ \ \ \ \ \|\ \ \ \|\ \ \ \_|\ \ \ \___|_
\ \ _ _\ \ \_|/_\ \ \ __\ \ \ \ __ \ \ _ _\ \ \ \\ \ \_____ \
\ \ \\ \\ \ \_|\ \ \ \|\__\_\ \ \ \ \ \ \ \\ \\ \ \_\\ \|____|\ \
\ \__\\ _\\ \_______\ \____________\ \__\ \__\ \__\\ _\\ \_______\____\_\ \
\|__|\|__|\|_______|\|____________|\|__|\|__|\|__|\|__|\|_______|\_________\
\|_________|
**/
contract DungeonRewards is IDungeonRewards, IDNGToken, FxBaseRootTunnel, Ownable {
/*///////////////////////////////////////////////////////////////
STORAGE
//////////////////////////////////////////////////////////////*/
ERC721 public dungeonContract;
ERC721 public avatarContract;
ERC721 public questContract;
struct Staker {
uint256[] stakedDungeons;
uint256 dungeonStakedOn; // timestamp of when holder first staked their dungeon(s) (used to calculated eligibility for avatars).
uint256[] stakedAvatars;
uint256 avatarStakedOn; // timestamp of when holder first staked their avatar(s)
uint256[] stakedQuests;
uint256 questStakedOn; // timestamp of when holder first staked their quest(s)
}
mapping(address => Staker) public userInfo;
bool public stakingPaused;
constructor(
address checkpointManager,
address fxRoot,
address _dungeonContract
) FxBaseRootTunnel(checkpointManager, fxRoot) {
dungeonContract = ERC721(_dungeonContract);
}
// @notice Set the contract addresses for all future instances.
function setContractAddresses(
address _avatarContract,
address _questContract
) public onlyOwner {
avatarContract = ERC721(_avatarContract);
questContract = ERC721(_questContract);
}
// Pause staking and unstaking
function setStakingPaused(bool paused) public onlyOwner {
stakingPaused = paused;
}
// For collab.land to give a role based on staking status
function balanceOf(address owner) public view returns (uint256) {
if(balanceOfDungeons(owner)>0 && balanceOfAvatars(owner)>0 && balanceOfQuests(owner)>0) return 3;
if(balanceOfDungeons(owner)>0 && balanceOfAvatars(owner)>0 && balanceOfQuests(owner)==0) return 2;
if(balanceOfDungeons(owner)>0 && balanceOfAvatars(owner)==0 && balanceOfQuests(owner)==0) return 1;
return 0;
}
// so we can confirm whether a wallet holds any staked dungeons, useful for Generative Avatars gas-only mint
function balanceOfDungeons(address owner) public view returns (uint256) {
return userInfo[owner].stakedDungeons.length;
}
// so we can confirm when a wallet staked their dungeons, useful for Generative Avatars gas-only mint
function dungeonFirstStaked(address owner) public view returns (uint256) {
return userInfo[owner].dungeonStakedOn;
}
function balanceOfAvatars(address owner) public view returns (uint256) {
return userInfo[owner].stakedAvatars.length;
}
function avatarFirstStaked(address owner) public view returns (uint256) {
return userInfo[owner].avatarStakedOn;
}
function balanceOfQuests(address owner) public view returns (uint256) {
return userInfo[owner].stakedQuests.length;
}
function questFirstStaked(address owner) public view returns (uint256) {
return userInfo[owner].questStakedOn;
}
// get staked tokens for address
function getStakedTokens(address user) public view returns (
uint256[] memory dungeons,
uint256[] memory avatars,
uint256[] memory quests
)
{
Staker memory staker = userInfo[user];
return (
staker.stakedDungeons,
staker.stakedAvatars,
staker.stakedQuests
);
}
function bulkStake(
uint256[] memory dungeons,
uint256[] memory avatars,
uint256[] memory quests
) public {
if (dungeons.length > 0) stakeMultipleDungeons(dungeons);
if (avatars.length > 0) stakeMultipleAvatars(avatars);
if (quests.length > 0) stakeMultipleQuests(quests);
}
function bulkUnstake(
uint256[] memory dungeons,
uint256[] memory avatars,
uint256[] memory quests
) public {
if (dungeons.length > 0) unstakeMultipleDungeons(dungeons);
if (avatars.length > 0) unstakeMultipleAvatars(avatars);
if (quests.length > 0) unstakeMultipleQuests(quests);
}
function stakeMultipleDungeons(uint256[] memory tokenIds) public {
require(!stakingPaused, "Staking currently paused.");
require(tokenIds.length>0, "No tokenIds provided.");
Staker storage staker = userInfo[msg.sender];
if (staker.dungeonStakedOn == 0) { // set our dungeon staked on once (if they unstake, it resets to zero and will be reset when they stake again)
staker.dungeonStakedOn = block.timestamp;
}
for (uint256 i = 0; i < tokenIds.length; i++) {
staker.stakedDungeons.push(tokenIds[i]);
dungeonContract.transferFrom(
msg.sender,
address(this),
tokenIds[i]
);
}
// start accumulating $DNG rewards on polygon
_sendMessageToChild(
abi.encode(
msg.sender,
uint256(NftType.Dungeon),
tokenIds.length,
true
)
);
}
function unstakeMultipleDungeons(uint256[] memory tokenIds) public {
require(!stakingPaused, "Staking is currently paused.");
Staker storage staker = userInfo[msg.sender];
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
require(containsElement(staker.stakedDungeons, tokenId), "Not dungeon owner.");
dungeonContract.transferFrom(
address(this),
msg.sender,
tokenId
);
removeDungeonFromStaker(staker, tokenId);
}
if (staker.stakedDungeons.length == 0) { // no more staked dungeons?
staker.dungeonStakedOn = 0; // then we reset the staked on date to 0 (so can be set to block.timestamp when it's staked again)
}
// stop accumulating $DNG rewards on polygon for these dungeons
_sendMessageToChild(
abi.encode(
msg.sender,
uint256(NftType.Dungeon),
tokenIds.length,
false
)
);
}
// Stake a single Dungeon (separate function to optimize for gas)
// @param tokenId The tokenId of the dungeon to stake
function stakeDungeon(uint256 tokenId) external {
require(!stakingPaused, "Staking is currently paused.");
Staker storage staker = userInfo[msg.sender];
staker.stakedDungeons.push(tokenId);
dungeonContract.transferFrom(
msg.sender,
address(this),
tokenId
);
if (staker.dungeonStakedOn == 0) { // set our dungeon staked on once (if they unstake, it resets to zero and will be reset when they stake again)
staker.dungeonStakedOn = block.timestamp;
}
// start accumulating $DNG rewards on polygon
_sendMessageToChild(
abi.encode(
msg.sender,
uint256(NftType.Dungeon),
1,
true
)
);
}
// Unstake a Dungeon
// @param tokenId The tokenId of the dungeon to unstake
function unstakeDungeon(uint256 tokenId) external {
require(!stakingPaused, "Staking is currently paused.");
Staker storage staker = userInfo[msg.sender];
require(containsElement(staker.stakedDungeons, tokenId), "Not dungeon owner.");
dungeonContract.transferFrom(
address(this),
msg.sender,
tokenId
);
removeDungeonFromStaker(staker, tokenId);
if (staker.stakedDungeons.length == 0) { // no more staked dungeons?
staker.dungeonStakedOn = 0; // then we reset the staked on date to 0 (so can be set to block.timestamp when it's staked again)
}
// stop accumulating $DNG rewards on polygon for these dungeons
_sendMessageToChild(
abi.encode(
msg.sender,
uint256(NftType.Dungeon),
1,
false
)
);
}
function stakeMultipleAvatars(uint256[] memory tokenIds) public {
require(!stakingPaused, "Staking currently paused.");
require(tokenIds.length>0, "No tokenIds provided.");
Staker storage staker = userInfo[msg.sender];
if (staker.avatarStakedOn == 0) { // set our avatar staked on once (if they unstake, it resets to zero and will be reset when they stake again)
staker.avatarStakedOn = block.timestamp;
}
for (uint256 i = 0; i < tokenIds.length; i++) {
staker.stakedAvatars.push(tokenIds[i]);
avatarContract.transferFrom(
msg.sender,
address(this),
tokenIds[i]
);
}
// start accumulating $DNG rewards on polygon
_sendMessageToChild(
abi.encode(
msg.sender,
uint256(NftType.Avatar),
tokenIds.length,
true
)
);
}
function unstakeMultipleAvatars(uint256[] memory tokenIds) public {
require(!stakingPaused, "Staking is currently paused.");
Staker storage staker = userInfo[msg.sender];
for (uint256 i = 0; i < tokenIds.length; i++) {
uint256 tokenId = tokenIds[i];
require(containsElement(...
// [truncated — 59611 bytes total]
Read Contract
SEND_MESSAGE_EVENT_SIG 0x0e387de6 → bytes32
avatarContract 0x45f0791d → address
avatarFirstStaked 0xcc581d79 → uint256
balanceOf 0x70a08231 → uint256
balanceOfAvatars 0xa6197a9f → uint256
balanceOfDungeons 0x3eee69a9 → uint256
balanceOfQuests 0x3f02d59e → uint256
checkpointManager 0xc0857ba0 → address
dungeonContract 0xf79e4164 → address
dungeonFirstStaked 0x3ac4b3ac → uint256
fxChildTunnel 0x972c4928 → address
fxRoot 0xde9b771f → address
getStakedTokens 0x63c28db1 → uint256[], uint256[], uint256[]
onERC721Received 0x150b7a02 → bytes4
owner 0x8da5cb5b → address
processedExits 0x607f2d42 → bool
questContract 0x6a6940cc → address
questFirstStaked 0xbded9a7c → uint256
stakingPaused 0xbbb781cc → bool
supportsInterface 0x01ffc9a7 → bool
userInfo 0x1959a002 → uint256, uint256, uint256
Write Contract 20 functions
These functions modify contract state and require a wallet transaction to execute.
bulkStake 0xd3397850
uint256[] dungeons
uint256[] avatars
uint256[] quests
bulkUnstake 0x0e1db437
uint256[] dungeons
uint256[] avatars
uint256[] quests
receiveMessage 0xf953cec7
bytes inputData
renounceOwnership 0x715018a6
No parameters
setContractAddresses 0xcd931e40
address _avatarContract
address _questContract
setFxChildTunnel 0xaea4e49e
address _fxChildTunnel
setStakingPaused 0x15b31bbb
bool paused
stakeAvatar 0xc6a54924
uint256 tokenId
stakeDungeon 0xd9c65c27
uint256 tokenId
stakeMultipleAvatars 0x840d6dcf
uint256[] tokenIds
stakeMultipleDungeons 0x8d18fa62
uint256[] tokenIds
stakeMultipleQuests 0x795b396d
uint256[] tokenIds
stakeQuest 0x4f04eba4
uint256 tokenId
transferOwnership 0xf2fde38b
address _newOwner
unstakeAvatar 0x998a1d15
uint256 tokenId
unstakeDungeon 0x3723148e
uint256 tokenId
unstakeMultipleAvatars 0xd0b05d35
uint256[] tokenIds
unstakeMultipleDungeons 0xad280eb0
uint256[] tokenIds
unstakeMultipleQuests 0xa04b29b9
uint256[] tokenIds
unstakeQuest 0xc714b768
uint256 tokenId
Recent Transactions
No transactions found for this address