Cryo Explorer Ethereum Mainnet

Address Contract Partially Verified

Address 0xD502F487e1841Fdc805130e13eae80c61186Bc98
Balance 0 ETH
Nonce 1
Code Size 9162 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

9162 bytes
0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c806370a082311161011a578063a9059cbb116100ad578063d01dd6d21161007c578063d01dd6d2146106b6578063dd62ed3e146106e4578063e7a324dc14610712578063f1127ed81461071a578063fe575a8714610774576101fb565b8063a9059cbb14610610578063aa271e1a1461063c578063b4b5ea5714610662578063cf456ae714610688576101fb565b80638da5cb5b116100e95780638da5cb5b1461058d57806395d89b41146105955780639b3957e51461059d578063a457c2d7146105e4576101fb565b806370a08231146104ba57806376db0696146104e0578063782d6fe11461051f5780637ecebe0014610567576101fb565b80633408e470116101925780634334614a116101615780634334614a14610406578063544d85641461042c578063587cde1e1461046e5780635c19a95c14610494576101fb565b80633408e47014610389578063395093511461039157806340c10f19146103bd57806342966c68146103e9576101fb565b806318160ddd116101ce57806318160ddd1461031357806320606b701461032d57806323b872dd14610335578063313ce5671461036b576101fb565b806306fdde0314610200578063095ea7b31461027d5780630d895ee1146102bd57806313af4035146102ed575b600080fd5b61020861079a565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561024257818101518382015260200161022a565b50505050905090810190601f16801561026f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102a96004803603604081101561029357600080fd5b506001600160a01b0381351690602001356107be565b604080519115158252519081900360200190f35b6102eb600480360360408110156102d357600080fd5b506001600160a01b038135169060200135151561086f565b005b6102eb6004803603602081101561030357600080fd5b50356001600160a01b031661091d565b61031b6109bb565b60408051918252519081900360200190f35b61031b6109c1565b6102a96004803603606081101561034b57600080fd5b506001600160a01b038135811691602081013590911690604001356109e5565b610373610b23565b6040805160ff9092168252519081900360200190f35b61031b610b28565b6102a9600480360360408110156103a757600080fd5b506001600160a01b038135169060200135610b2c565b6102eb600480360360408110156103d357600080fd5b506001600160a01b038135169060200135610bf7565b6102eb600480360360208110156103ff57600080fd5b5035610cda565b6102a96004803603602081101561041c57600080fd5b50356001600160a01b0316610eb0565b6104526004803603602081101561044257600080fd5b50356001600160a01b0316610ec5565b604080516001600160a01b039092168252519081900360200190f35b6104526004803603602081101561048457600080fd5b50356001600160a01b0316610f0b565b6102eb600480360360208110156104aa57600080fd5b50356001600160a01b0316610f26565b61031b600480360360208110156104d057600080fd5b50356001600160a01b0316610fff565b610506600480360360208110156104f657600080fd5b50356001600160a01b0316611023565b6040805163ffffffff9092168252519081900360200190f35b61054b6004803603604081101561053557600080fd5b506001600160a01b03813516906020013561103b565b604080516001600160601b039092168252519081900360200190f35b61031b6004803603602081101561057d57600080fd5b50356001600160a01b031661104e565b610452611060565b61020861106f565b6102eb600480360360c08110156105b357600080fd5b506001600160a01b038135169060208101359060408101359060ff6060820135169060808101359060a0013561108f565b6102a9600480360360408110156105fa57600080fd5b506001600160a01b038135169060200135611422565b6102a96004803603604081101561062657600080fd5b506001600160a01b038135169060200135611549565b6102a96004803603602081101561065257600080fd5b50356001600160a01b03166115dc565b61054b6004803603602081101561067857600080fd5b50356001600160a01b03166115f1565b6102eb6004803603604081101561069e57600080fd5b506001600160a01b0381351690602001351515611639565b6102eb600480360360408110156106cc57600080fd5b506001600160a01b03813516906020013515156116e7565b61031b600480360360408110156106fa57600080fd5b506001600160a01b0381358116916020013516611795565b61031b6117c9565b61074c6004803603604081101561073057600080fd5b5080356001600160a01b0316906020013563ffffffff166117ed565b6040805163ffffffff90931683526001600160601b0390911660208301528051918290030190f35b6102a96004803603602081101561078a57600080fd5b50356001600160a01b031661181f565b60405180604001604052806008815260200167125b9d1959dc985b60c21b81525081565b336000908152600a602052604081205460ff161580156107f757506001600160a01b0383166000908152600a602052604090205460ff16155b610839576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b600060001983146108525761084d83611936565b610856565b6000195b9050610863338583611985565b60019150505b92915050565b6003546001600160a01b031633146108bd576040805162461bcd60e51b815260206004820152600c60248201526b24aa2fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038216600081815260056020908152604091829020805460ff1916851515908117909155825190815291517fd28dc1379d750c7c8137c7ef7b074f62f1361b9becc7f9d77d8c0d6e46a3cd069281900390910190a25050565b6003546001600160a01b0316331461096b576040805162461bcd60e51b815260206004820152600c60248201526b24aa2fa327a92124a22222a760a11b604482015290519081900360640190fd5b600380546001600160a01b0319166001600160a01b0383811691909117918290556040519116907f50146d0e3c60aa1d17a70635b05494f864e86144a2201275021014fbf08bafe290600090a250565b60025481565b7f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a86681565b336000818152600a602052604081205490919060ff16158015610a2157506001600160a01b0385166000908152600a602052604090205460ff16155b8015610a4657506001600160a01b0384166000908152600a602052604090205460ff16155b610a88576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b6000610a9384611936565b6001600160a01b038088166000818152600760209081526040808320948816808452949091529020549293506001600160601b039092169114801590610ae257506001600160601b0381811614155b15610b0b576000610afc6001600160601b038316846118d4565b9050610b09888583611985565b505b610b16878784611a63565b5060019695505050505050565b601281565b4690565b336000908152600a602052604081205460ff16158015610b6557506001600160a01b0383166000908152600a602052604090205460ff16155b610ba7576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b6000610bb283611936565b3360008181526007602090815260408083206001600160a01b038a168452909152902054919250610863918690610bf2906001600160601b03168561187e565b611985565b3360009081526004602052604090205460ff16610c51576040805162461bcd60e51b8152602060048201526013602482015272125517d3d3931657d5d2125511531254d51151606a1b604482015290519081900360640190fd5b336000908152600a602052604090205460ff16158015610c8a57506001600160a01b0382166000908152600a602052604090205460ff16155b610ccc576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b610cd68282611bb1565b5050565b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1680610d2257503360009081526005602052604090205460ff165b610d69576040805162461bcd60e51b8152602060048201526013602482015272125517d3d3931657d5d2125511531254d51151606a1b604482015290519081900360640190fd5b336000908152600a602052604090205460ff1615610dbf576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b6000610dca82611936565b9050610e118260405180604001604052806016815260200175125517d253959053125117d095549397d05353d5539560521b815250600254611c789092919063ffffffff16565b60025533600090815260066020526040902054610e37906001600160601b0316826118d4565b33600081815260066020908152604080832080546001600160601b0319166001600160601b0396909616959095179094558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3610cd6610ea833610ec5565b600083611d10565b60056020526000908152604090205460ff1681565b6001600160a01b0381811660009081526008602052604081205490911615610f07576001600160a01b0380831660009081526008602052604090205416610869565b5090565b6008602052600090815260409020546001600160a01b031681565b336000908152600a602052604090205460ff16158015610f5f57506001600160a01b0381166000908152600a602052604090205460ff16155b610fa1576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b6001600160a01b038116610ff2576040805162461bcd60e51b815260206004820152601360248201527249545f494e56414c49445f44454c454741544560681b604482015290519081900360640190fd5b610ffc3382611e97565b50565b6001600160a01b03166000908152600660205260409020546001600160601b031690565b60016020526000908152604090205463ffffffff1681565b60006110478383611f27565b9392505050565b60096020526000908152604090205481565b6003546001600160a01b031681565b6040518060400160405280600481526020016324aa23a960e11b81525081565b336000908152600a602052604090205460ff161580156110c857506001600160a01b0386166000908152600a602052604090205460ff16155b61110a576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b83421115611156576040805162461bcd60e51b8152602060048201526014602482015273125517d4d251d3905515549157d156141254915160621b604482015290519081900360640190fd5b6001600160a01b0386166111a7576040805162461bcd60e51b815260206004820152601360248201527249545f494e56414c49445f44454c454741544560681b604482015290519081900360640190fd5b604080518082019091526008815267125b9d1959dc985b60c21b60209091015260007f8cad95687ba82c2ce50e74f7b754645e5117c3a5bec8151c0726d5857980a8667fe4517f9c6567471bcdce783f7a5548e35240e4fa5d2f5b9980b258adcca8f657611213610b28565b60408051602080820195909552808201939093526060830191909152306080808401919091528151808403909101815260a0830182528051908401207f559ecdc56deb20a8459e4cf815474e49f61cc42291343e2a6973295dd8139baa60c08401526001600160a01b038b1660e084015261010083018a90526101208084018a9052825180850390910181526101408401835280519085012061190160f01b6101608501526101628401829052610182808501829052835180860390910181526101a285018085528151918701919091206000918290526101c2860180865281905260ff8b166101e287015261020286018a90526102228601899052935192965090949293909260019261024280840193601f198301929081900390910190855afa158015611346573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166113a5576040805162461bcd60e51b815260206004820152601460248201527349545f494e56414c49445f5349474e415455524560601b604482015290519081900360640190fd5b6001600160a01b0381166000908152600960205260409020805460018101909155891461140c576040805162461bcd60e51b815260206004820152601060248201526f49545f494e56414c49445f4e4f4e434560801b604482015290519081900360640190fd5b611416818b611e97565b50505050505050505050565b336000908152600a602052604081205460ff1615801561145b57506001600160a01b0383166000908152600a602052604090205460ff16155b61149d576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b60006114a883611936565b3360009081526007602090815260408083206001600160a01b03891684529091529020549091506001600160601b03908116908216811015611526576040805162461bcd60e51b815260206004820152601260248201527149545f43414e4e4f545f444543524541534560701b604482015290519081900360640190fd5b61153e3386610bf26001600160601b038516866118d4565b506001949350505050565b336000908152600a602052604081205460ff1615801561158257506001600160a01b0383166000908152600a602052604090205460ff16155b6115c4576040805162461bcd60e51b815260206004820152600e60248201526d125517d0931050d2d31254d5115160921b604482015290519081900360640190fd5b60006115cf83611936565b9050610863338583611a63565b60046020526000908152604090205460ff1681565b6001600160a01b0316600090815260208181526040808320600183528184205463ffffffff90811660001901168452909152902054600160201b90046001600160601b031690565b6003546001600160a01b03163314611687576040805162461bcd60e51b815260206004820152600c60248201526b24aa2fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b038216600081815260046020908152604091829020805460ff1916851515908117909155825190815291517f583b0aa0e528532caf4b907c11d7a8158a122fe2a6fb80cd9b09776ebea8d92d9281900390910190a25050565b6003546001600160a01b03163314611735576040805162461bcd60e51b815260206004820152600c60248201526b24aa2fa327a92124a22222a760a11b604482015290519081900360640190fd5b6001600160a01b0382166000818152600a6020908152604091829020805460ff1916851515908117909155825190815291517fd347f3377aa78fbf3d569e645590833e6f1f2ad4acb059e8924c12628bf649f19281900390910190a25050565b6001600160a01b0391821660009081526007602090815260408083209390941682529190915220546001600160601b031690565b7f559ecdc56deb20a8459e4cf815474e49f61cc42291343e2a6973295dd8139baa81565b600060208181529281526040808220909352908152205463ffffffff811690600160201b90046001600160601b031682565b600a6020526000908152604090205460ff1681565b80820182811015610869576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b8181016001600160601b038084169082161015610869576040805162461bcd60e51b815260206004820152600f60248201526e534d5f4144445f4f564552464c4f5760881b604482015290519081900360640190fd5b6000826001600160601b0316826001600160601b03161115611930576040805162461bcd60e51b815260206004820152601060248201526f534d5f5355425f554e444552464c4f5760801b604482015290519081900360640190fd5b50900390565b6000600160601b8210610f07576040805162461bcd60e51b815260206004820152601260248201527149545f455843454544535f39365f4249545360701b604482015290519081900360640190fd5b6001600160a01b038316158015906119a557506001600160a01b03821615155b6119e8576040805162461bcd60e51b815260206004820152600f60248201526e49545f414444524553535f5a45524f60881b604482015290519081900360640190fd5b6001600160a01b0383811660008181526007602090815260408083209487168084529482529182902080546001600160601b0319166001600160601b038716908117909155825190815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b6001600160a01b038216611aae576040805162461bcd60e51b815260206004820152600d60248201526c49545f494e56414c49445f544f60981b604482015290519081900360640190fd5b6001600160a01b038316600090815260066020526040902054611ada906001600160601b0316826118d4565b6001600160a01b0384811660009081526006602052604080822080546001600160601b0319166001600160601b0395861617905591851681522054611b2091168261187e565b6001600160a01b0383811660008181526006602090815260409182902080546001600160601b0319166001600160601b039687161790558151948616855290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a3611bac611b9d84610ec5565b611ba684610ec5565b83611d10565b505050565b6000611bbc82611936565b600254909150611bcc9083611834565b6002556001600160a01b038316600090815260066020526040902054611bfb906001600160601b03168261187e565b6001600160a01b038416600081815260066020908152604080832080546001600160601b0319166001600160601b03969096169590951790945583518681529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a3611bac6000611ba685610ec5565b8183038184821115611d085760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611ccd578181015183820152602001611cb5565b50505050905090810190601f168015611cfa5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b816001600160a01b0316836001600160a01b03161480611d3757506001600160601b038116155b15611d4157611bac565b6001600160a01b03831615611e17576001600160a01b03831660009081526001602052604090205463ffffffff1680611db9576040805162461bcd60e51b8152602060048201526015602482015274564f5f494e53554646494349454e545f564f54455360581b604482015290519081900360640190fd5b6001600160a01b03841660009081526020818152604080832063ffffffff60001986018116855292528220546001600160601b03600160201b909104169190611e0690839086906118d416565b9050611e13868483612158565b5050505b6001600160a01b03821615611bac576001600160a01b03821660009081526001602090815260408083205483835281842063ffffffff9182166000198101831686529352908320549192600160201b9092046001600160601b03169190611e82908390869061187e16565b9050611e8f858483612158565b505050505050565b6000611ea283610ec5565b6001600160a01b03848116600081815260066020908152604080832054600890925280832080546001600160a01b03191689871690811790915590519596506001600160601b03909116949093861692917ffeb33bf853fe1792904c8eb8d9051f75733847700e159cdb11cf8721a700a01091a4611f21828483611d10565b50505050565b6000438210611f75576040805162461bcd60e51b81526020600482015260156024820152741593d7d393d517d6515517d1115511549352539151605a1b604482015290519081900360640190fd5b6001600160a01b03831660009081526001602052604090205463ffffffff1680611fa3576000915050610869565b6001600160a01b03841660009081526020818152604080832063ffffffff60001986018116855292529091205416831061201b576001600160a01b0384166000908152602081815260408083206000199490940163ffffffff1683529290522054600160201b90046001600160601b03169050610869565b6001600160a01b03841660009081526020818152604080832083805290915290205463ffffffff16831015612054576000915050610869565b600060001982015b8163ffffffff168163ffffffff16111561211557600282820363ffffffff1604810361208661237d565b506001600160a01b03871660009081526020818152604080832063ffffffff858116855290835292819020815180830190925254928316808252600160201b9093046001600160601b031691810191909152908714156120f0576020015194506108699350505050565b805163ffffffff168711156121075781935061210e565b6001820392505b505061205c565b506001600160a01b03851660009081526020818152604080832063ffffffff909416835292905220546001600160601b03600160201b9091041691505092915050565b60006121634361232e565b6001600160a01b038516600090815260208181526040808320600019880163ffffffff9081168552925290912054919250600160201b9091046001600160601b0316908416158015906121e557506001600160a01b03851660009081526020818152604080832063ffffffff6000198901811685529252909120548382169116145b15612242576001600160a01b038516600090815260208181526040808320600019880163ffffffff168452909152902080546fffffffffffffffffffffffff000000001916600160201b6001600160601b038616021790556122da565b60408051808201825263ffffffff84811682526001600160601b0386811660208085019182526001600160a01b038b1660008181528083528781208c87168252835287812096518754945163ffffffff19958616918816919091176fffffffffffffffffffffffff000000001916600160201b9190961602949094179095559382526001938490529390208054909316918701161790555b604080516001600160601b0380841682528516602082015281516001600160a01b038816927f664ef4a22338e827df5b675ec1747eac10c2ea611e1c575f3d96c38a2e24231e928290030190a25050505050565b6000600160201b8210610f07576040805162461bcd60e51b8152602060048201526012602482015271564f5f455843454544535f33325f4249545360701b604482015290519081900360640190fd5b60408051808201909152600080825260208201529056fea2646970667358221220604e62d4ca23eaeecf3f7cbab0b97e3f5c95db5725fa4b06c149d143faa0307864736f6c63430007050033

Verified Source Code Partial Match

Compiler: v0.7.5+commit.eb77ed08 EVM: istanbul Optimization: Yes (200 runs)
Votes.sol 117 lines
// SPDX-License-Identifier: GPL-3.0-or-later

// CODE COPIED FROM COMPOUND PROTOCOL (https://github.com/compound-finance/compound-protocol/tree/b9b14038612d846b83f8a009a82c38974ff2dcfe)

// Copyright 2020 Compound Labs, Inc.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// CODE WAS SLIGHTLY MODIFIED

// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'SafeMath.sol';

contract Votes {
    using SafeMath for uint96;

    struct Checkpoint {
        uint32 fromBlock;
        uint96 votes;
    }

    mapping(address => mapping(uint32 => Checkpoint)) public checkpoints;
    mapping(address => uint32) public checkpointsLength;

    event DelegateVotesChanged(address indexed account, uint96 oldVotes, uint96 newVotes);

    function getCurrentVotes(address account) external view returns (uint96) {
        // out of bounds access is safe and returns 0 votes
        return checkpoints[account][checkpointsLength[account] - 1].votes;
    }

    function _getPriorVotes(address account, uint256 blockNumber) internal view returns (uint96) {
        require(blockNumber < block.number, 'VO_NOT_YET_DETERMINED');

        uint32 n = checkpointsLength[account];
        if (n == 0) {
            return 0;
        }

        if (checkpoints[account][n - 1].fromBlock <= blockNumber) {
            return checkpoints[account][n - 1].votes;
        }

        if (checkpoints[account][0].fromBlock > blockNumber) {
            return 0;
        }

        uint32 lower = 0;
        uint32 upper = n - 1;
        while (upper > lower) {
            uint32 center = upper - (upper - lower) / 2;
            Checkpoint memory checkpoint = checkpoints[account][center];
            if (checkpoint.fromBlock == blockNumber) {
                return checkpoint.votes;
            } else if (checkpoint.fromBlock < blockNumber) {
                lower = center;
            } else {
                upper = center - 1;
            }
        }
        return checkpoints[account][lower].votes;
    }

    function _updateVotes(
        address giver,
        address receiver,
        uint96 votes
    ) internal {
        if (giver == receiver || votes == 0) {
            return;
        }
        if (giver != address(0)) {
            uint32 n = checkpointsLength[giver];
            require(n > 0, 'VO_INSUFFICIENT_VOTES');
            // out of bounds access is safe and returns 0 votes
            uint96 oldVotes = checkpoints[giver][n - 1].votes;
            uint96 newVotes = oldVotes.sub96(votes);
            _writeCheckpoint(giver, n, newVotes);
        }

        if (receiver != address(0)) {
            uint32 n = checkpointsLength[receiver];
            // out of bounds access is safe and returns 0 votes
            uint96 oldVotes = checkpoints[receiver][n - 1].votes;
            uint96 newVotes = oldVotes.add96(votes);
            _writeCheckpoint(receiver, n, newVotes);
        }
    }

    function _writeCheckpoint(
        address account,
        uint32 n,
        uint96 votes
    ) internal {
        uint32 blockNumber = safe32(block.number);
        // out of bounds access is safe and returns 0 votes
        uint96 oldVotes = checkpoints[account][n - 1].votes;
        if (n > 0 && checkpoints[account][n - 1].fromBlock == blockNumber) {
            checkpoints[account][n - 1].votes = votes;
        } else {
            checkpoints[account][n] = Checkpoint(blockNumber, votes);
            checkpointsLength[account] = n + 1;
        }
        emit DelegateVotesChanged(account, oldVotes, votes);
    }

    function safe32(uint256 n) internal pure returns (uint32) {
        require(n < 2**32, 'VO_EXCEEDS_32_BITS');
        return uint32(n);
    }
}
SafeMath.sol 88 lines
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, 'SM_ADD_OVERFLOW');
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        z = sub(x, y, 'SM_SUB_UNDERFLOW');
    }

    function sub(
        uint256 x,
        uint256 y,
        string memory message
    ) internal pure returns (uint256 z) {
        require((z = x - y) <= x, message);
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW');
    }

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

    function ceil_div(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = div(a, b);
        if (c == mul(a, b)) {
            return c;
        } else {
            return add(c, 1);
        }
    }

    function safe32(uint256 n) internal pure returns (uint32) {
        require(n < 2**32, 'IS_EXCEEDS_32_BITS');
        return uint32(n);
    }

    function add96(uint96 a, uint96 b) internal pure returns (uint96 c) {
        c = a + b;
        require(c >= a, 'SM_ADD_OVERFLOW');
    }

    function sub96(uint96 a, uint96 b) internal pure returns (uint96) {
        require(b <= a, 'SM_SUB_UNDERFLOW');
        return a - b;
    }

    function mul96(uint96 x, uint96 y) internal pure returns (uint96 z) {
        require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW');
    }

    function div96(uint96 a, uint96 b) internal pure returns (uint96) {
        require(b > 0, 'SM_DIV_BY_ZERO');
        uint96 c = a / b;
        return c;
    }

    function add32(uint32 a, uint32 b) internal pure returns (uint32 c) {
        c = a + b;
        require(c >= a, 'SM_ADD_OVERFLOW');
    }

    function sub32(uint32 a, uint32 b) internal pure returns (uint32) {
        require(b <= a, 'SM_SUB_UNDERFLOW');
        return a - b;
    }

    function mul32(uint32 x, uint32 y) internal pure returns (uint32 z) {
        require(y == 0 || (z = x * y) / y == x, 'SM_MUL_OVERFLOW');
    }

    function div32(uint32 a, uint32 b) internal pure returns (uint32) {
        require(b > 0, 'SM_DIV_BY_ZERO');
        uint32 c = a / b;
        return c;
    }
}
IntegralToken.sol 245 lines
// SPDX-License-Identifier: GPL-3.0-or-later

// CODE COPIED FROM COMPOUND PROTOCOL (https://github.com/compound-finance/compound-protocol/tree/b9b14038612d846b83f8a009a82c38974ff2dcfe)

// Copyright 2020 Compound Labs, Inc.
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// CODE WAS SLIGHTLY MODIFIED

// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

import 'IIntegralToken.sol';
import 'SafeMath.sol';
import 'Votes.sol';

contract IntegralToken is IIntegralToken, Votes {
    using SafeMath for uint256;
    using SafeMath for uint96;

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event OwnerSet(address indexed owner);
    event MinterSet(address indexed account, bool isMinter);
    event BurnerSet(address indexed account, bool isBurner);
    event Approval(address indexed owner, address indexed spender, uint256 amount);
    event DelegatesChanged(address indexed account, address indexed oldDelegate, address indexed newDelegate);
    event BlacklistedSet(address indexed account, bool isBlacklisted);

    string public constant name = 'Integral';
    string public constant symbol = 'ITGR';
    uint8 public constant decimals = 18;
    uint256 public totalSupply;
    address public owner;

    mapping(address => bool) public isMinter;
    mapping(address => bool) public isBurner;
    mapping(address => uint96) internal balances;
    mapping(address => mapping(address => uint96)) internal allowances;
    mapping(address => address) public delegates;
    mapping(address => uint256) public nonces;
    mapping(address => bool) public isBlacklisted;

    bytes32 public constant DOMAIN_TYPEHASH =
        keccak256('EIP712Domain(string name,uint256 chainId,address verifyingContract)');
    bytes32 public constant DELEGATION_TYPEHASH =
        keccak256('Delegation(address newDelegate,uint256 nonce,uint256 expiry)');

    constructor(address account, uint256 _initialAmount) {
        owner = msg.sender;
        isMinter[msg.sender] = true;
        isBurner[msg.sender] = true;
        _mint(account, _initialAmount);
    }

    function balanceOf(address account) external view returns (uint256) {
        return balances[account];
    }

    function allowance(address account, address spender) external view returns (uint256) {
        return allowances[account][spender];
    }

    function setOwner(address _owner) external {
        require(msg.sender == owner, 'IT_FORBIDDEN');
        owner = _owner;
        emit OwnerSet(owner);
    }

    function setMinter(address account, bool _isMinter) external {
        require(msg.sender == owner, 'IT_FORBIDDEN');
        isMinter[account] = _isMinter;
        emit MinterSet(account, _isMinter);
    }

    function mint(address to, uint256 _amount) external override {
        require(isMinter[msg.sender], 'IT_ONLY_WHITELISTED');
        require(!isBlacklisted[msg.sender] && !isBlacklisted[to], 'IT_BLACKLISTED');
        _mint(to, _amount);
    }

    function _mint(address to, uint256 _amount) internal {
        uint96 amount = safe96(_amount);
        totalSupply = totalSupply.add(_amount);
        balances[to] = balances[to].add96(amount);
        emit Transfer(address(0), to, _amount);

        _updateVotes(address(0), getDelegate(to), amount);
    }

    function setBurner(address account, bool _isBurner) external {
        require(msg.sender == owner, 'IT_FORBIDDEN');
        isBurner[account] = _isBurner;
        emit BurnerSet(account, _isBurner);
    }

    function burn(uint256 _amount) external {
        require(isBurner[address(0)] || isBurner[msg.sender], 'IT_ONLY_WHITELISTED');
        require(!isBlacklisted[msg.sender], 'IT_BLACKLISTED');
        uint96 amount = safe96(_amount);
        totalSupply = totalSupply.sub(_amount, 'IT_INVALID_BURN_AMOUNT');
        balances[msg.sender] = balances[msg.sender].sub96(amount);
        emit Transfer(msg.sender, address(0), _amount);

        _updateVotes(getDelegate(msg.sender), address(0), amount);
    }

    function approve(address spender, uint256 _amount) external returns (bool) {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[spender], 'IT_BLACKLISTED');
        uint96 amount = _amount == uint256(-1) ? uint96(-1) : safe96(_amount);
        _approve(msg.sender, spender, amount);
        return true;
    }

    function _approve(
        address account,
        address spender,
        uint96 amount
    ) internal {
        require(account != address(0) && spender != address(0), 'IT_ADDRESS_ZERO');
        allowances[account][spender] = amount;
        emit Approval(account, spender, amount);
    }

    function increaseAllowance(address spender, uint256 _extraAmount) external returns (bool) {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[spender], 'IT_BLACKLISTED');
        uint96 extraAmount = safe96(_extraAmount);
        _approve(msg.sender, spender, allowances[msg.sender][spender].add96(extraAmount));
        return true;
    }

    function decreaseAllowance(address spender, uint256 _subtractedAmount) external returns (bool) {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[spender], 'IT_BLACKLISTED');
        uint96 subtractedAmount = safe96(_subtractedAmount);
        uint96 currentAmount = allowances[msg.sender][spender];
        require(currentAmount >= subtractedAmount, 'IT_CANNOT_DECREASE');
        _approve(msg.sender, spender, currentAmount.sub96(subtractedAmount));
        return true;
    }

    function transfer(address to, uint256 _amount) external returns (bool) {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[to], 'IT_BLACKLISTED');
        uint96 amount = safe96(_amount);
        _transferTokens(msg.sender, to, amount);
        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 _amount
    ) external returns (bool) {
        address spender = msg.sender;
        require(!isBlacklisted[spender] && !isBlacklisted[from] && !isBlacklisted[to], 'IT_BLACKLISTED');
        uint96 amount = safe96(_amount);
        uint96 spenderAllowance = allowances[from][spender];
        if (spender != from && spenderAllowance != uint96(-1)) {
            uint96 newAllowance = spenderAllowance.sub96(amount);
            _approve(from, spender, newAllowance);
        }
        _transferTokens(from, to, amount);
        return true;
    }

    function _transferTokens(
        address from,
        address to,
        uint96 amount
    ) internal {
        require(to != address(0), 'IT_INVALID_TO');
        balances[from] = balances[from].sub96(amount);
        balances[to] = balances[to].add96(amount);
        emit Transfer(from, to, amount);
        _updateVotes(getDelegate(from), getDelegate(to), amount);
    }

    function getPriorVotes(address account, uint256 blockNumber) public view returns (uint96) {
        return _getPriorVotes(account, blockNumber);
    }

    function getDelegate(address account) public view returns (address) {
        return delegates[account] == address(0) ? account : delegates[account];
    }

    function delegate(address newDelegate) external {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[newDelegate], 'IT_BLACKLISTED');
        require(newDelegate != address(0), 'IT_INVALID_DELEGATE');
        _delegateFrom(msg.sender, newDelegate);
    }

    function _delegateFrom(address from, address newDelegate) internal {
        address oldDelegate = getDelegate(from);
        uint96 delegatorBalance = balances[from];
        delegates[from] = newDelegate;

        emit DelegatesChanged(from, oldDelegate, newDelegate);

        _updateVotes(oldDelegate, newDelegate, delegatorBalance);
    }

    function delegateWithSignature(
        address newDelegate,
        uint256 nonce,
        uint256 expiry,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external {
        require(!isBlacklisted[msg.sender] && !isBlacklisted[newDelegate], 'IT_BLACKLISTED');
        require(block.timestamp <= expiry, 'IT_SIGNATURE_EXPIRED');
        require(newDelegate != address(0), 'IT_INVALID_DELEGATE');
        bytes32 domainSeparator = keccak256(
            abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this))
        );
        bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, newDelegate, nonce, expiry));
        bytes32 digest = keccak256(abi.encodePacked('\x19\x01', domainSeparator, structHash));
        address signatory = ecrecover(digest, v, r, s);
        require(signatory != address(0), 'IT_INVALID_SIGNATURE');
        require(nonce == nonces[signatory]++, 'IT_INVALID_NONCE');
        _delegateFrom(signatory, newDelegate);
    }

    function safe96(uint256 n) internal pure returns (uint96) {
        require(n < 2**96, 'IT_EXCEEDS_96_BITS');
        return uint96(n);
    }

    function getChainId() public pure returns (uint256) {
        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        return chainId;
    }

    function setBlacklisted(address account, bool _isBlacklisted) external {
        require(msg.sender == owner, 'IT_FORBIDDEN');
        isBlacklisted[account] = _isBlacklisted;
        emit BlacklistedSet(account, _isBlacklisted);
    }
}
IIntegralToken.sol 8 lines
// SPDX-License-Identifier: GPL-3.0-or-later
// Deployed with donations via Gitcoin GR9

pragma solidity 0.7.5;

interface IIntegralToken {
    function mint(address to, uint256 amount) external;
}

Read Contract

DELEGATION_TYPEHASH 0xe7a324dc → bytes32
DOMAIN_TYPEHASH 0x20606b70 → bytes32
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
checkpoints 0xf1127ed8 → uint32, uint96
checkpointsLength 0x76db0696 → uint32
decimals 0x313ce567 → uint8
delegates 0x587cde1e → address
getChainId 0x3408e470 → uint256
getCurrentVotes 0xb4b5ea57 → uint96
getDelegate 0x544d8564 → address
getPriorVotes 0x782d6fe1 → uint96
isBlacklisted 0xfe575a87 → bool
isBurner 0x4334614a → bool
isMinter 0xaa271e1a → bool
name 0x06fdde03 → string
nonces 0x7ecebe00 → uint256
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256

Write Contract 13 functions

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

approve 0x095ea7b3
address spender
uint256 _amount
returns: bool
burn 0x42966c68
uint256 _amount
decreaseAllowance 0xa457c2d7
address spender
uint256 _subtractedAmount
returns: bool
delegate 0x5c19a95c
address newDelegate
delegateWithSignature 0x9b3957e5
address newDelegate
uint256 nonce
uint256 expiry
uint8 v
bytes32 r
bytes32 s
increaseAllowance 0x39509351
address spender
uint256 _extraAmount
returns: bool
mint 0x40c10f19
address to
uint256 _amount
setBlacklisted 0xd01dd6d2
address account
bool _isBlacklisted
setBurner 0x0d895ee1
address account
bool _isBurner
setMinter 0xcf456ae7
address account
bool _isMinter
setOwner 0x13af4035
address _owner
transfer 0xa9059cbb
address to
uint256 _amount
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 _amount
returns: bool

Recent Transactions

No transactions found for this address