Address Contract Partially Verified
Address
0x2234a7c690AF5de948B3a1CcbEa43705E4583D2d
Balance
0 ETH
Nonce
1
Code Size
14622 bytes
Creator
0x93bC2E40...ac0e at tx 0x15f788de...136047
Indexed Transactions
0
Contract Bytecode
14622 bytes
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c806386bfdb19116100f9578063d27761ef11610097578063ec16bf4711610071578063ec16bf47146104f6578063ee5b11c314610512578063f2fde38b14610542578063f7f2e80d1461055e576101c4565b8063d27761ef1461048e578063e390ddde146104be578063ec06a89a146104da576101c4565b80638da5cb5b116100d35780638da5cb5b14610403578063ae49945d14610421578063b61d27f61461043f578063b754021914610470576101c4565b806386bfdb191461039857806388660611146103cb5780638980f11f146103e7576101c4565b806370c8f7fe1161016657806381d81d2a1161014057806381d81d2a1461030057806381d8b3f81461033057806382eac7f01461034c578063843d96f21461037c576101c4565b806370c8f7fe146102a7578063715018a6146102c35780637c43215f146102cd576101c4565b806320263e87116101a257806320263e87146102355780632f1d5a601461025357806345c126261461026f57806360976e6f1461028b576101c4565b806303ea9f1f146101c95780630f37b6ba146101f9578063127effb214610217575b600080fd5b6101e360048036038101906101de9190612abf565b61057a565b6040516101f09190612b05565b60405180910390f35b610201610592565b60405161020e9190612b05565b60405180910390f35b61021f6106ab565b60405161022c9190612b2f565b60405180910390f35b61023d6106d1565b60405161024a9190612b2f565b60405180910390f35b61026d60048036038101906102689190612abf565b6106f7565b005b61028960048036038101906102849190612b76565b61079e565b005b6102a560048036038101906102a09190612bb6565b610e3f565b005b6102c160048036038101906102bc9190612b76565b610e51565b005b6102cb610ff2565b005b6102e760048036038101906102e29190612abf565b611006565b6040516102f79493929190612bfe565b60405180910390f35b61031a60048036038101906103159190612abf565b61113e565b6040516103279190612b05565b60405180910390f35b61034a60048036038101906103459190612c6f565b6111e8565b005b61036660048036038101906103619190612bb6565b611501565b6040516103739190612b2f565b60405180910390f35b61039660048036038101906103919190612caf565b611540565b005b6103b260048036038101906103ad9190612abf565b611b63565b6040516103c29493929190612d2a565b60405180910390f35b6103e560048036038101906103e09190612d6f565b611ce4565b005b61040160048036038101906103fc9190612b76565b611e9b565b005b61040b611eb2565b6040516104189190612b2f565b60405180910390f35b610429611edb565b6040516104369190612b2f565b60405180910390f35b61045960048036038101906104549190612e14565b611f01565b604051610467929190612f18565b60405180910390f35b610478611f90565b6040516104859190612b05565b60405180910390f35b6104a860048036038101906104a39190612abf565b611f96565b6040516104b59190612f48565b60405180910390f35b6104d860048036038101906104d39190612abf565b611fb6565b005b6104f460048036038101906104ef9190612c6f565b612128565b005b610510600480360381019061050b9190612f63565b612433565b005b61052c60048036038101906105279190612abf565b61262e565b6040516105399190612f48565b60405180910390f35b61055c60048036038101906105579190612abf565b61264e565b005b61057860048036038101906105739190612fb6565b6126d1565b005b60086020528060005260406000206000915090505481565b6000806000905060005b6004805490508110156106a35760066000600483815481106105c1576105c0613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16610690576106826004828154811061065257610651613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661113e565b8261068d9190613067565b91505b808061069b9061309b565b91505061059c565b508091505090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6106ff6127d7565b7f2709918445f306d3e94d280907c62c5d2525ac3192d2e544774c7f181d65af3e600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16826040516107529291906130e3565b60405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b81600560008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1680156108455750600660008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff16155b610884576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161087b90613169565b60405180910390fd5b6009546108908261113e565b116108d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c7906131d5565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061095e575061092f611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61099d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099490613241565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16856040518363ffffffff1660e01b8152600401610a61929190613261565b6020604051808303816000875af1158015610a80573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa4919061329f565b506000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1685600660008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600660008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600660008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015489604051602401610c63969594939291906132cc565b6040516020818303038152906040527fb649fbf4000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051610ced9190613369565b600060405180830381855af49150503d8060008114610d28576040519150601f19603f3d011682016040523d82523d6000602084013e610d2d565b606091505b5050905080610d71576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d68906133cc565b60405180910390fd5b42600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206006018190555083600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600701819055507ff17784554852232b03320852ce4646e3da26e60c45891d2364716686a80a41048585604051610e30929190613261565b60405180910390a15050505050565b610e476127d7565b8060098190555050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480610edf5750610eb0611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b610f1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f1590613241565b60405180910390fd5b6000610f298361113e565b90506000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f9a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fbe9190613425565b600a610fca9190613585565b8284610fd691906135d0565b610fe09190613641565b9050610fec848261079e565b50505050565b610ffa6127d7565b6110046000612855565b565b600080600080600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169350600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600601549250600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600701549150600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff1690509193509193565b600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166370a08231846040518263ffffffff1660e01b815260040161119f9190612b2f565b602060405180830381865afa1580156111bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111e09190613687565b915050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806112765750611247611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6112b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ac90613241565b60405180910390fd5b60006112bf610592565b905060005b6004805490508110156114fb57828015611365575060076000600483815481106112f1576112f0613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156113b6576113b16004828154811061138157611380613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611fb6565b6114e8565b60066000600483815481106113ce576113cd613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff1615801561149857506009546114966004838154811061146657611465613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661113e565b115b156114e7576114e6600482815481106114b4576114b3613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685846126d1565b5b5b80806114f39061309b565b9150506112c4565b50505050565b6004818154811061151157600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806115ce575061159f611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61160d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160490613241565b60405180910390fd5b600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561182e5783600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060040181905550611b1d565b6001600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055506004859080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518061010001604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff168152602001828152602001600015158152602001600081526020016000815250600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060608201518160030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506080820151816004015560a08201518160050160006101000a81548160ff02191690831515021790555060c0820151816006015560e082015181600701559050505b7f5446ab0ba7c017f50a3b977101d494eff5d7d9b6f5d9a22515377006c309438a8583868685604051611b549594939291906136b4565b60405180910390a15050505050565b600080600080600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169250600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169150600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169350600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206004015490509193509193565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161480611d725750611d43611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b611db1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611da890613241565b60405180910390fd5b600560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615611e975780600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160006101000a81548160ff0219169083151502179055507f86a5c093bb99c6d06a96c424a351d83258cf9b1438445e973896d74c3edf64eb8282604051611e8e929190613707565b60405180910390a15b5050565b611ea36127d7565b611eae823383612919565b5050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006060611f0d6127d7565b6000808773ffffffffffffffffffffffffffffffffffffffff16878787604051611f38929190613764565b60006040518083038185875af1925050503d8060008114611f75576040519150601f19603f3d011682016040523d82523d6000602084013e611f7a565b606091505b5091509150818193509350505094509492505050565b60095481565b60076020528060005260406000206000915054906101000a900460ff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806120445750612015611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612083576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207a90613241565b60405180910390fd5b600760008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612125576000600860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050612123828261079e565b505b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806121b65750612187611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b6121f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ec90613241565b60405180910390fd5b60005b60048054905081101561242e578180156122995750600760006004838154811061222557612224613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b156122ea576122e5600482815481106122b5576122b4613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16611fb6565b61241b565b600660006004838154811061230257612301613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060050160009054906101000a900460ff161580156123cc57506009546123ca6004838154811061239a57612399613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661113e565b115b1561241a57612419600482815481106123e8576123e7613009565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684610e51565b5b5b80806124269061309b565b9150506121f8565b505050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806124c15750612492611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b612500576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124f790613241565b60405180910390fd5b600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156126295781600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555080600860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055507f70d7e641df56680393a21230bdc277feec8e8da8af9bdcc93f2bc14f83596ddb8383836040516126209392919061377d565b60405180910390a15b505050565b60056020528060005260406000206000915054906101000a900460ff1681565b6126566127d7565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036126c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126bc90613826565b60405180910390fd5b6126ce81612855565b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061275f5750612730611eb2565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b61279e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279590613241565b60405180910390fd5b60006127a98461113e565b905060008282856127ba91906135d0565b6127c49190613641565b90506127d0858261079e565b5050505050565b6127df612a4f565b73ffffffffffffffffffffffffffffffffffffffff166127fd611eb2565b73ffffffffffffffffffffffffffffffffffffffff1614612853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284a90613892565b60405180910390fd5b565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb858560405160240161294b929190613261565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516129999190613369565b6000604051808303816000865af19150503d80600081146129d6576040519150601f19603f3d011682016040523d82523d6000602084013e6129db565b606091505b5091509150818015612a095750600081511480612a08575080806020019051810190612a07919061329f565b5b5b612a48576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a3f906138fe565b60405180910390fd5b5050505050565b600033905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a8c82612a61565b9050919050565b612a9c81612a81565b8114612aa757600080fd5b50565b600081359050612ab981612a93565b92915050565b600060208284031215612ad557612ad4612a57565b5b6000612ae384828501612aaa565b91505092915050565b6000819050919050565b612aff81612aec565b82525050565b6000602082019050612b1a6000830184612af6565b92915050565b612b2981612a81565b82525050565b6000602082019050612b446000830184612b20565b92915050565b612b5381612aec565b8114612b5e57600080fd5b50565b600081359050612b7081612b4a565b92915050565b60008060408385031215612b8d57612b8c612a57565b5b6000612b9b85828601612aaa565b9250506020612bac85828601612b61565b9150509250929050565b600060208284031215612bcc57612bcb612a57565b5b6000612bda84828501612b61565b91505092915050565b60008115159050919050565b612bf881612be3565b82525050565b6000608082019050612c136000830187612bef565b612c206020830186612af6565b612c2d6040830185612af6565b612c3a6060830184612bef565b95945050505050565b612c4c81612be3565b8114612c5757600080fd5b50565b600081359050612c6981612c43565b92915050565b60008060408385031215612c8657612c85612a57565b5b6000612c9485828601612b61565b9250506020612ca585828601612c5a565b9150509250929050565b600080600080600060a08688031215612ccb57612cca612a57565b5b6000612cd988828901612aaa565b9550506020612cea88828901612aaa565b9450506040612cfb88828901612aaa565b9350506060612d0c88828901612aaa565b9250506080612d1d88828901612b61565b9150509295509295909350565b6000608082019050612d3f6000830187612b20565b612d4c6020830186612b20565b612d596040830185612b20565b612d666060830184612af6565b95945050505050565b60008060408385031215612d8657612d85612a57565b5b6000612d9485828601612aaa565b9250506020612da585828601612c5a565b9150509250929050565b600080fd5b600080fd5b600080fd5b60008083601f840112612dd457612dd3612daf565b5b8235905067ffffffffffffffff811115612df157612df0612db4565b5b602083019150836001820283011115612e0d57612e0c612db9565b5b9250929050565b60008060008060608587031215612e2e57612e2d612a57565b5b6000612e3c87828801612aaa565b9450506020612e4d87828801612b61565b935050604085013567ffffffffffffffff811115612e6e57612e6d612a5c565b5b612e7a87828801612dbe565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b60005b83811015612ec2578082015181840152602081019050612ea7565b60008484015250505050565b6000601f19601f8301169050919050565b6000612eea82612e88565b612ef48185612e93565b9350612f04818560208601612ea4565b612f0d81612ece565b840191505092915050565b6000604082019050612f2d6000830185612bef565b8181036020830152612f3f8184612edf565b90509392505050565b6000602082019050612f5d6000830184612bef565b92915050565b600080600060608486031215612f7c57612f7b612a57565b5b6000612f8a86828701612aaa565b9350506020612f9b86828701612c5a565b9250506040612fac86828701612b61565b9150509250925092565b600080600060608486031215612fcf57612fce612a57565b5b6000612fdd86828701612aaa565b9350506020612fee86828701612b61565b9250506040612fff86828701612b61565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061307282612aec565b915061307d83612aec565b925082820190508082111561309557613094613038565b5b92915050565b60006130a682612aec565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036130d8576130d7613038565b5b600182019050919050565b60006040820190506130f86000830185612b20565b6131056020830184612b20565b9392505050565b600082825260208201905092915050565b7f506f6f6c206973206e6f74206163746976650000000000000000000000000000600082015250565b600061315360128361310c565b915061315e8261311d565b602082019050919050565b6000602082019050818103600083015261318281613146565b9050919050565b7f506f6f6c20697320736d616c6c00000000000000000000000000000000000000600082015250565b60006131bf600d8361310c565b91506131ca82613189565b602082019050919050565b600060208201905081810360008301526131ee816131b2565b9050919050565b7f4e6f74206f776e6572206f72206f70657261746f720000000000000000000000600082015250565b600061322b60158361310c565b9150613236826131f5565b602082019050919050565b6000602082019050818103600083015261325a8161321e565b9050919050565b60006040820190506132766000830185612b20565b6132836020830184612af6565b9392505050565b60008151905061329981612c43565b92915050565b6000602082840312156132b5576132b4612a57565b5b60006132c38482850161328a565b91505092915050565b600060c0820190506132e16000830189612b20565b6132ee6020830188612b20565b6132fb6040830187612b20565b6133086060830186612b20565b6133156080830185612af6565b61332260a0830184612af6565b979650505050505050565b600081905092915050565b600061334382612e88565b61334d818561332d565b935061335d818560208601612ea4565b80840191505092915050565b60006133758284613338565b915081905092915050565b7f64656c656761746563616c6c206661696c656400000000000000000000000000600082015250565b60006133b660138361310c565b91506133c182613380565b602082019050919050565b600060208201905081810360008301526133e5816133a9565b9050919050565b600060ff82169050919050565b613402816133ec565b811461340d57600080fd5b50565b60008151905061341f816133f9565b92915050565b60006020828403121561343b5761343a612a57565b5b600061344984828501613410565b91505092915050565b60008160011c9050919050565b6000808291508390505b60018511156134a95780860481111561348557613484613038565b5b60018516156134945780820291505b80810290506134a285613452565b9450613469565b94509492505050565b6000826134c2576001905061357e565b816134d0576000905061357e565b81600181146134e657600281146134f05761351f565b600191505061357e565b60ff84111561350257613501613038565b5b8360020a91508482111561351957613518613038565b5b5061357e565b5060208310610133831016604e8410600b84101617156135545782820a90508381111561354f5761354e613038565b5b61357e565b613561848484600161345f565b9250905081840481111561357857613577613038565b5b81810290505b9392505050565b600061359082612aec565b915061359b836133ec565b92506135c87fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff84846134b2565b905092915050565b60006135db82612aec565b91506135e683612aec565b92508282026135f481612aec565b9150828204841483151761360b5761360a613038565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061364c82612aec565b915061365783612aec565b92508261366757613666613612565b5b828204905092915050565b60008151905061368181612b4a565b92915050565b60006020828403121561369d5761369c612a57565b5b60006136ab84828501613672565b91505092915050565b600060a0820190506136c96000830188612b20565b6136d66020830187612b20565b6136e36040830186612b20565b6136f06060830185612b20565b6136fd6080830184612af6565b9695505050505050565b600060408201905061371c6000830185612b20565b6137296020830184612bef565b9392505050565b82818337600083830152505050565b600061374b838561332d565b9350613758838584613730565b82840190509392505050565b600061377182848661373f565b91508190509392505050565b60006060820190506137926000830186612b20565b61379f6020830185612bef565b6137ac6040830184612af6565b949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061381060268361310c565b915061381b826137b4565b604082019050919050565b6000602082019050818103600083015261383f81613803565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061387c60208361310c565b915061388782613846565b602082019050919050565b600060208201905081810360008301526138ab8161386f565b9050919050565b7f5472616e7366657248656c7065723a205452414e534645525f4641494c454400600082015250565b60006138e8601f8361310c565b91506138f3826138b2565b602082019050919050565b60006020820190508181036000830152613917816138db565b905091905056
Verified Source Code Partial Match
Compiler: v0.8.21+commit.d9974bed
EVM: london
Optimization: No
IFxs.sol 46 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
interface IFxs {
function DEFAULT_ADMIN_ROLE() external view returns(bytes32);
function FRAXStablecoinAdd() external view returns(address);
function FXS_DAO_min() external view returns(uint256);
function allowance(address owner, address spender) external view returns(uint256);
function approve(address spender, uint256 amount) external returns(bool);
function balanceOf(address account) external view returns(uint256);
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
function checkpoints(address, uint32) external view returns(uint32 fromBlock, uint96 votes);
function decimals() external view returns(uint8);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns(bool);
function genesis_supply() external view returns(uint256);
function getCurrentVotes(address account) external view returns(uint96);
function getPriorVotes(address account, uint256 blockNumber) external view returns(uint96);
function getRoleAdmin(bytes32 role) external view returns(bytes32);
function getRoleMember(bytes32 role, uint256 index) external view returns(address);
function getRoleMemberCount(bytes32 role) external view returns(uint256);
function grantRole(bytes32 role, address account) external;
function hasRole(bytes32 role, address account) external view returns(bool);
function increaseAllowance(address spender, uint256 addedValue) external returns(bool);
function mint(address to, uint256 amount) external;
function name() external view returns(string memory);
function numCheckpoints(address) external view returns(uint32);
function oracle_address() external view returns(address);
function owner_address() external view returns(address);
function pool_burn_from(address b_address, uint256 b_amount) external;
function pool_mint(address m_address, uint256 m_amount) external;
function renounceRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function setFRAXAddress(address frax_contract_address) external;
function setFXSMinDAO(uint256 min_FXS) external;
function setOracle(address new_oracle) external;
function setOwner(address _owner_address) external;
function setTimelock(address new_timelock) external;
function symbol() external view returns(string memory);
function timelock_address() external view returns(address);
function toggleVotes() external;
function totalSupply() external view returns(uint256);
function trackingVotes() external view returns(bool);
function transfer(address recipient, uint256 amount) external returns(bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns(bool);
}
IFrax.sol 73 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
interface IFrax {
function COLLATERAL_RATIO_PAUSER() external view returns (bytes32);
function DEFAULT_ADMIN_ADDRESS() external view returns (address);
function DEFAULT_ADMIN_ROLE() external view returns (bytes32);
function addPool(address pool_address ) external;
function allowance(address owner, address spender ) external view returns (uint256);
function approve(address spender, uint256 amount ) external returns (bool);
function balanceOf(address account ) external view returns (uint256);
function burn(uint256 amount ) external;
function burnFrom(address account, uint256 amount ) external;
function collateral_ratio_paused() external view returns (bool);
function controller_address() external view returns (address);
function creator_address() external view returns (address);
function decimals() external view returns (uint8);
function decreaseAllowance(address spender, uint256 subtractedValue ) external returns (bool);
function eth_usd_consumer_address() external view returns (address);
function eth_usd_price() external view returns (uint256);
function frax_eth_oracle_address() external view returns (address);
function frax_info() external view returns (uint256, uint256, uint256, uint256, uint256, uint256, uint256, uint256);
function frax_pools(address ) external view returns (bool);
function frax_pools_array(uint256 ) external view returns (address);
function frax_price() external view returns (uint256);
function frax_step() external view returns (uint256);
function fxs_address() external view returns (address);
function fxs_eth_oracle_address() external view returns (address);
function fxs_price() external view returns (uint256);
function genesis_supply() external view returns (uint256);
function getRoleAdmin(bytes32 role ) external view returns (bytes32);
function getRoleMember(bytes32 role, uint256 index ) external view returns (address);
function getRoleMemberCount(bytes32 role ) external view returns (uint256);
function globalCollateralValue() external view returns (uint256);
function global_collateral_ratio() external view returns (uint256);
function grantRole(bytes32 role, address account ) external;
function hasRole(bytes32 role, address account ) external view returns (bool);
function increaseAllowance(address spender, uint256 addedValue ) external returns (bool);
function last_call_time() external view returns (uint256);
function minting_fee() external view returns (uint256);
function name() external view returns (string memory);
function owner_address() external view returns (address);
function pool_burn_from(address b_address, uint256 b_amount ) external;
function pool_mint(address m_address, uint256 m_amount ) external;
function price_band() external view returns (uint256);
function price_target() external view returns (uint256);
function redemption_fee() external view returns (uint256);
function refreshCollateralRatio() external;
function refresh_cooldown() external view returns (uint256);
function removePool(address pool_address ) external;
function renounceRole(bytes32 role, address account ) external;
function revokeRole(bytes32 role, address account ) external;
function setController(address _controller_address ) external;
function setETHUSDOracle(address _eth_usd_consumer_address ) external;
function setFRAXEthOracle(address _frax_oracle_addr, address _weth_address ) external;
function setFXSAddress(address _fxs_address ) external;
function setFXSEthOracle(address _fxs_oracle_addr, address _weth_address ) external;
function setFraxStep(uint256 _new_step ) external;
function setMintingFee(uint256 min_fee ) external;
function setOwner(address _owner_address ) external;
function setPriceBand(uint256 _price_band ) external;
function setPriceTarget(uint256 _new_price_target ) external;
function setRedemptionFee(uint256 red_fee ) external;
function setRefreshCooldown(uint256 _new_cooldown ) external;
function setTimelock(address new_timelock ) external;
function symbol() external view returns (string memory);
function timelock_address() external view returns (address);
function toggleCollateralRatio() external;
function totalSupply() external view returns (uint256);
function transfer(address recipient, uint256 amount ) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount ) external returns (bool);
function weth_address() external view returns (address);
}
TransferHelper.sol 28 lines
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.11;
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
function safeApprove(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
}
function safeTransfer(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
}
IncentivizingLiquidityAMO.sol 400 lines
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.19;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ================== IncentivizingLiquidityAMO =======================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Primary Author(s)
// Amirnader Aghayeghazvini: https://github.com/amirnader-ghazvini
// Reviewer(s) / Contributor(s)
// Dennis: https://github.com/denett
import "./interfaces/IFrax.sol";
import "./interfaces/IFxs.sol";
import "./interfaces/IIncentivizationHandler.sol";
import "./Uniswap/TransferHelper.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract IncentivizingLiquidityAmo is Ownable {
/* ============================================= STATE VARIABLES ==================================================== */
// Addresses Config
address public operatorAddress;
address public targetTokenAddress; // Token that AMO incentivize
address public incentiveTokenAddress; // Token that AMO uses as an incentive
// Pools related
address[] public poolArray;
struct LiquidityPool {
// Pool Addresses
address poolAddress; // Where the actual tokens are in the pool
address incentivePoolAddress; // Contract that handle incentive distribution e.g. Bribe contract
address incentivizationHandlerAddress; // Incentive handler contract e.g. votemarket handler
address gaugeAddress; // Gauge address
uint256 incentivizationId; // Votemarket Bounty ID
bool isPaused;
uint lastIncentivizationTimestamp; // timestamp of last time this pool was incentivized
uint lastIncentivizationAmount; // Max amount of incentives
}
mapping(address => bool) public poolInitialized;
mapping(address => LiquidityPool) private poolInfo;
// Constant Incentivization can be set (e.g. DAO Deal)
mapping(address => bool) public poolHasFixedIncent;
mapping(address => uint256) public poolFixedIncentAmount; // Constant Incentivization amount
// Configurations
uint256 public minTvl; // Min TVL of pool for being considered for incentivization
/* =============================================== CONSTRUCTOR ====================================================== */
/// @notice constructor
/// @param _operatorAddress Address of AMO Operator
/// @param _targetTokenAddress Address of Token that AMO incentivize (e.g. crvFRAX)
/// @param _incentiveTokenAddress Address of Token that AMO uses as an incentive (e.g. FXS)
/// @param _minTvl Min TVL of pool for being considered for incentivization
constructor(
address _operatorAddress,
address _targetTokenAddress,
address _incentiveTokenAddress,
uint256 _minTvl
) Ownable() {
operatorAddress = _operatorAddress;
targetTokenAddress = _targetTokenAddress;
incentiveTokenAddress = _incentiveTokenAddress;
minTvl = _minTvl;
emit StartAMO(_operatorAddress, _targetTokenAddress, _incentiveTokenAddress);
}
/* ================================================ MODIFIERS ======================================================= */
modifier onlyByOwnerOperator() {
require(msg.sender == operatorAddress || msg.sender == owner(), "Not owner or operator");
_;
}
modifier activePool(address _poolAddress) {
require(poolInitialized[_poolAddress] && !poolInfo[_poolAddress].isPaused, "Pool is not active");
require(showPoolTvl(_poolAddress) > minTvl, "Pool is small");
_;
}
/* ================================================= EVENTS ========================================================= */
/// @notice The ```StartAMO``` event fires when the AMO deploys
/// @param _operatorAddress Address of operator
/// @param _targetTokenAddress Address of Token that AMO incentivize (e.g. crvFRAX)
/// @param _incentiveTokenAddress Address of Token that AMO uses as an incentive (e.g. FXS)
event StartAMO(address _operatorAddress, address _targetTokenAddress, address _incentiveTokenAddress);
/// @notice The ```SetOperator``` event fires when the operatorAddress is set
/// @param _oldAddress The original address
/// @param _newAddress The new address
event SetOperator(address _oldAddress, address _newAddress);
/// @notice The ```AddOrSetPool``` event fires when a pool is added or modified
/// @param _poolAddress The pool address
/// @param _gaugeAddress The gauge address
/// @param _incentivePoolAddress Contract that handle incentive distribution e.g. Bribe contract
/// @param _incentivizationHandlerAddress Incentive handler contract e.g. votemarket handler
/// @param _indexId indexID in Votium or Votemarket
event AddOrSetPool(
address _poolAddress,
address _gaugeAddress,
address _incentivePoolAddress,
address _incentivizationHandlerAddress,
uint256 _indexId
);
/// @notice The ```ChangePauseStatusPool``` event fires when a pool is added or modified
/// @param _poolAddress The pool address
/// @param _isPaused Pool Pause Status
event ChangePauseStatusPool(address _poolAddress, bool _isPaused);
/// @notice The ```SetPoolFixedIncent``` event fires when a pool's constant incentivization is updated
/// @param _poolAddress The pool address
/// @param _hasFixedIncent Pool Deal Status
/// @param _amountPerCycle Pool Deal Amount
event SetPoolFixedIncent(address _poolAddress, bool _hasFixedIncent, uint256 _amountPerCycle);
/// @notice The ```IncentivizePool``` event fires when a deposit happens to a pair
/// @param _poolAddress The pool address
/// @param _amount Incentive amount
event IncentivizePool(address _poolAddress, uint256 _amount);
/* ================================================== VIEWS ========================================================= */
/// @notice Show TVL of targeted token in all active pools
/// @return TVL of targeted token in all active pools
function showActivePoolsTvl() public view returns (uint256) {
uint tvl = 0;
for (uint i = 0; i < poolArray.length; i++) {
if (!poolInfo[poolArray[i]].isPaused) {
tvl += showPoolTvl(poolArray[i]);
}
}
return tvl;
}
/// @notice Show TVL of targeted token in liquidity pool
/// @param _poolAddress Address of liquidity pool
/// @return TVL of targeted token in liquidity pool
function showPoolTvl(address _poolAddress) public view returns (uint256) {
ERC20 targetToken = ERC20(targetTokenAddress);
return targetToken.balanceOf(_poolAddress);
}
/// @notice Show Pool parameters
/// @param _poolAddress Address of liquidity pool
/// @return _gaugeAddress Gauge Contract Address
/// @return _incentivePoolAddress Contract that handle incentive distribution e.g. Bribe contract
/// @return _incentivizationHandlerAddress Incentive handler contract e.g. votemarket handler
/// @return _incentivizationId Pool General Incentivization ID (e.g. in Votemarket it is BountyID)
function showPoolInfo(
address _poolAddress
)
external
view
returns (
address _gaugeAddress,
address _incentivePoolAddress,
address _incentivizationHandlerAddress,
uint256 _incentivizationId
)
{
_incentivePoolAddress = poolInfo[_poolAddress].incentivePoolAddress;
_incentivizationHandlerAddress = poolInfo[_poolAddress].incentivizationHandlerAddress;
_gaugeAddress = poolInfo[_poolAddress].gaugeAddress;
_incentivizationId = poolInfo[_poolAddress].incentivizationId;
}
/// @notice Show Pool status
/// @param _poolAddress Address of liquidity pool
/// @return _isInitialized Pool registered or not
/// @return _lastIncentivizationTimestamp timestamp of last time this pool was incentivized
/// @return _lastIncentivizationAmount last cycle incentive amount
/// @return _isPaused puased or not
function showPoolStatus(
address _poolAddress
)
external
view
returns (
bool _isInitialized,
uint _lastIncentivizationTimestamp,
uint _lastIncentivizationAmount,
bool _isPaused
)
{
_isInitialized = poolInitialized[_poolAddress];
_lastIncentivizationTimestamp = poolInfo[_poolAddress].lastIncentivizationTimestamp;
_lastIncentivizationAmount = poolInfo[_poolAddress].lastIncentivizationAmount;
_isPaused = poolInfo[_poolAddress].isPaused;
}
/* ============================================== INCENTIVIZATION FUNCTIONS ==================================================== */
/// @notice Function to deposit incentives to one pool
/// @param _poolAddress Address of liquidity pool
/// @param _amount Amount of incentives to be deposited
function incentivizePoolByAmount(
address _poolAddress,
uint256 _amount
) public activePool(_poolAddress) onlyByOwnerOperator {
ERC20 _incentiveToken = ERC20(incentiveTokenAddress);
_incentiveToken.approve(poolInfo[_poolAddress].incentivePoolAddress, _amount);
(bool success, ) = poolInfo[_poolAddress].incentivizationHandlerAddress.delegatecall(
abi.encodeWithSignature(
"incentivizePool(address,address,address,address,uint256,uint256)",
_poolAddress,
poolInfo[_poolAddress].gaugeAddress,
poolInfo[_poolAddress].incentivePoolAddress,
incentiveTokenAddress,
poolInfo[_poolAddress].incentivizationId,
_amount
)
);
require(success, "delegatecall failed");
poolInfo[_poolAddress].lastIncentivizationTimestamp = block.timestamp;
poolInfo[_poolAddress].lastIncentivizationAmount = _amount;
emit IncentivizePool(_poolAddress, _amount);
}
/// @notice Function to deposit incentives to one pool (based on ratio)
/// @param _poolAddress Address of liquidity pool
/// @param _totalIncentAmount Total budget for incentivization
/// @param _totalTvl Total active pools TVL
function incentivizePoolByTvl(
address _poolAddress,
uint256 _totalIncentAmount,
uint256 _totalTvl
) public onlyByOwnerOperator {
uint256 _poolTvl = showPoolTvl(_poolAddress);
uint256 _amount = (_totalIncentAmount * _poolTvl) / _totalTvl;
incentivizePoolByAmount(_poolAddress, _amount);
}
/// @notice Function to deposit incentives to one pool (based on budget per unit)
/// @param _poolAddress Address of liquidity pool
/// @param _unitIncentAmount Incentive per single unit of target Token
function incentivizePoolByUnitBudget(
address _poolAddress,
uint256 _unitIncentAmount
) public onlyByOwnerOperator {
uint256 _poolTvl = showPoolTvl(_poolAddress);
uint256 _amount = (_unitIncentAmount * _poolTvl) / (10 ** ERC20(targetTokenAddress).decimals());
incentivizePoolByAmount(_poolAddress, _amount);
}
/// @notice Function to deposit incentives to one pool (based on Constant Incentivization)
/// @param _poolAddress Address of liquidity pool
function incentivizePoolByFixedIncent(
address _poolAddress
) public onlyByOwnerOperator {
if (poolHasFixedIncent[_poolAddress]){
uint256 _amount = poolFixedIncentAmount[_poolAddress];
incentivizePoolByAmount(_poolAddress, _amount);
}
}
/// Functions For depositing incentives to all active pools
/// @notice Function to deposit incentives to all active pools (based on TVL ratio)
/// @param _totalIncentAmount Total Incentive budget
/// @param _FixedIncent Incentivize considering FixedIncent
function incentivizeAllPoolsByTvl(uint256 _totalIncentAmount, bool _FixedIncent) public onlyByOwnerOperator {
uint256 _totalTvl = showActivePoolsTvl();
for (uint i = 0; i < poolArray.length; i++) {
if (_FixedIncent && poolHasFixedIncent[poolArray[i]]) {
incentivizePoolByFixedIncent(poolArray[i]);
} else if (!poolInfo[poolArray[i]].isPaused && showPoolTvl(poolArray[i]) > minTvl) {
incentivizePoolByTvl(poolArray[i], _totalIncentAmount, _totalTvl);
}
}
}
/// @notice Function to deposit incentives to all active pools (based on budget per unit of target Token)
/// @param _unitIncentAmount Incentive per single unit of target Token
/// @param _FixedIncent Incentivize considering FixedIncent
function incentivizeAllPoolsByUnitBudget(uint256 _unitIncentAmount, bool _FixedIncent) public onlyByOwnerOperator {
for (uint i = 0; i < poolArray.length; i++) {
if (_FixedIncent && poolHasFixedIncent[poolArray[i]]) {
incentivizePoolByFixedIncent(poolArray[i]);
} else if (!poolInfo[poolArray[i]].isPaused && showPoolTvl(poolArray[i]) > minTvl) {
incentivizePoolByUnitBudget(poolArray[i], _unitIncentAmount);
}
}
}
/// @notice Add/Set liquidity pool
/// @param _poolAddress Address of liquidity pool
/// @param _incentivePoolAddress Contract that handle incentive distribution e.g. Bribe contract
/// @param _incentivizationHandlerAddress Incentive handler contract e.g. votemarket handler
/// @param _gaugeAddress Address of liquidity pool gauge
/// @param _incentivizationId Pool General Incentivization ID (e.g. in Votemarket it is BountyID)
function addOrSetPool(
address _poolAddress,
address _incentivePoolAddress,
address _incentivizationHandlerAddress,
address _gaugeAddress,
uint256 _incentivizationId
) external onlyByOwnerOperator {
if (poolInitialized[_poolAddress]) {
poolInfo[_poolAddress].incentivePoolAddress = _incentivePoolAddress;
poolInfo[_poolAddress].incentivizationHandlerAddress = _incentivizationHandlerAddress;
poolInfo[_poolAddress].gaugeAddress = _gaugeAddress;
poolInfo[_poolAddress].incentivizationId = _incentivizationId;
} else {
poolInitialized[_poolAddress] = true;
poolArray.push(_poolAddress);
poolInfo[_poolAddress] = LiquidityPool({
poolAddress: _poolAddress,
incentivePoolAddress: _incentivePoolAddress,
incentivizationHandlerAddress: _incentivizationHandlerAddress,
gaugeAddress: _gaugeAddress,
lastIncentivizationTimestamp: 0,
lastIncentivizationAmount: 0,
isPaused: false,
incentivizationId: _incentivizationId
});
}
emit AddOrSetPool(
_poolAddress,
_gaugeAddress,
_incentivePoolAddress,
_incentivizationHandlerAddress,
_incentivizationId
);
}
/// @notice Pause/Unpause liquidity pool
/// @param _poolAddress Address of liquidity pool
/// @param _isPaused bool
function pausePool(address _poolAddress, bool _isPaused) external onlyByOwnerOperator {
if (poolInitialized[_poolAddress]) {
poolInfo[_poolAddress].isPaused = _isPaused;
emit ChangePauseStatusPool(_poolAddress, _isPaused);
}
}
/// @notice Add/Change/Remove Constant Incentivization can be set (e.g. DAO Deal)
/// @param _poolAddress Address of liquidity pool
/// @param _hasFixedIncent bool
/// @param _amountPerCycle Amount of constant incentives
function setFixedIncent(address _poolAddress, bool _hasFixedIncent, uint256 _amountPerCycle) external onlyByOwnerOperator {
if (poolInitialized[_poolAddress]) {
poolHasFixedIncent[_poolAddress] = _hasFixedIncent;
poolFixedIncentAmount[_poolAddress] = _amountPerCycle;
emit SetPoolFixedIncent(_poolAddress, _hasFixedIncent, _amountPerCycle);
}
}
/* ====================================== RESTRICTED GOVERNANCE FUNCTIONS =========================================== */
/// @notice Change the Operator address
/// @param _newOperatorAddress Operator address
function setOperatorAddress(address _newOperatorAddress) external onlyOwner {
emit SetOperator(operatorAddress, _newOperatorAddress);
operatorAddress = _newOperatorAddress;
}
/// @notice Change the Min TVL for incentivization
/// @param _minTvl Min TVL of pool for being considered for incentivization
function setMinTvl(uint256 _minTvl) external onlyOwner {
minTvl = _minTvl;
}
/// @notice Recover ERC20 tokens
/// @param tokenAddress address of ERC20 token
/// @param tokenAmount amount to be withdrawn
function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {
// Can only be triggered by owner
TransferHelper.safeTransfer(address(tokenAddress), msg.sender, tokenAmount);
}
// Generic proxy
function execute(
address _to,
uint256 _value,
bytes calldata _data
) external onlyOwner returns (bool, bytes memory) {
(bool success, bytes memory result) = _to.call{ value: _value }(_data);
return (success, result);
}
}
IIncentivizationHandler.sol 12 lines
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;
interface IIncentivizationHandler {
function incentivizePool(
address poolAddress,
address gaugeAddress,
address incentivePoolAdderss,
address incentiveTokenAddress,
uint256 indexId,
uint256 amount) external;
}
Address.sol 244 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
Context.sol 24 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
Ownable.sol 83 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
ERC20.sol 365 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address to, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
* - the caller must have allowance for ``from``'s tokens of at least
* `amount`.
*/
function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
/**
* @dev Moves `amount` of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `from` must have a balance of at least `amount`.
*/
function _transfer(address from, address to, uint256 amount) internal virtual {
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
// Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
// decrementing then incrementing.
_balances[to] += amount;
}
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
unchecked {
// Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
_balances[account] += amount;
}
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
// Overflow not possible: amount <= accountBalance <= totalSupply.
_totalSupply -= amount;
}
emit Transfer(account, address(0), amount);
_afterTokenTransfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `amount`.
*
* Does not update the allowance amount in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Might emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(currentAllowance >= amount, "ERC20: insufficient allowance");
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* has been transferred to `to`.
* - when `from` is zero, `amount` tokens have been minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens have been burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}
IERC20.sol 78 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}
SafeERC20.sol 143 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to
* 0 before setting it to a non-zero value.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
IERC20Permit.sol 60 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
IERC20Metadata.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
Read Contract
incentiveTokenAddress 0x20263e87 → address
minTvl 0xb7540219 → uint256
operatorAddress 0x127effb2 → address
owner 0x8da5cb5b → address
poolArray 0x82eac7f0 → address
poolFixedIncentAmount 0x03ea9f1f → uint256
poolHasFixedIncent 0xd27761ef → bool
poolInitialized 0xee5b11c3 → bool
showActivePoolsTvl 0x0f37b6ba → uint256
showPoolInfo 0x86bfdb19 → address, address, address, uint256
showPoolStatus 0x7c43215f → bool, uint256, uint256, bool
showPoolTvl 0x81d81d2a → uint256
targetTokenAddress 0xae49945d → address
Write Contract 15 functions
These functions modify contract state and require a wallet transaction to execute.
addOrSetPool 0x843d96f2
address _poolAddress
address _incentivePoolAddress
address _incentivizationHandlerAddress
address _gaugeAddress
uint256 _incentivizationId
execute 0xb61d27f6
address _to
uint256 _value
bytes _data
returns: bool, bytes
incentivizeAllPoolsByTvl 0x81d8b3f8
uint256 _totalIncentAmount
bool _FixedIncent
incentivizeAllPoolsByUnitBudget 0xec06a89a
uint256 _unitIncentAmount
bool _FixedIncent
incentivizePoolByAmount 0x45c12626
address _poolAddress
uint256 _amount
incentivizePoolByFixedIncent 0xe390ddde
address _poolAddress
incentivizePoolByTvl 0xf7f2e80d
address _poolAddress
uint256 _totalIncentAmount
uint256 _totalTvl
incentivizePoolByUnitBudget 0x70c8f7fe
address _poolAddress
uint256 _unitIncentAmount
pausePool 0x88660611
address _poolAddress
bool _isPaused
recoverERC20 0x8980f11f
address tokenAddress
uint256 tokenAmount
renounceOwnership 0x715018a6
No parameters
setFixedIncent 0xec16bf47
address _poolAddress
bool _hasFixedIncent
uint256 _amountPerCycle
setMinTvl 0x60976e6f
uint256 _minTvl
setOperatorAddress 0x2f1d5a60
address _newOperatorAddress
transferOwnership 0xf2fde38b
address newOwner
Recent Transactions
No transactions found for this address