Coder Social home page Coder Social logo

gh's Introduction

gh's People

Contributors

godhunter97 avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

owenlp

gh's Issues

Pancake

/**
*Submitted for verification at BscScan.com on 2020-10-30
*/

/*

  • @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 GSN 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.
    */
    contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, which should be used via inheritance.
    constructor() internal {}

    function _msgSender() internal view returns (address payable) {
    return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
    this; // silence state mutability warning without generating bytecode - see ethereum/solidity#2691
    return msg.data;
    }
    }

/**

  • @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.
    */
    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() internal {
      address msgSender = _msgSender();
      _owner = msgSender;
      emit OwnershipTransferred(address(0), msgSender);
      }

    /**

    • @dev Returns the address of the current owner.
      */
      function owner() public view returns (address) {
      return _owner;
      }

    /**

    • @dev Throws if called by any account other than the owner.
      */
      modifier onlyOwner() {
      require(_owner == _msgSender(), 'Ownable: caller is not the owner');
      _;
      }

    /**

    • @dev Leaves the contract without owner. It will not be possible to call
    • onlyOwner functions anymore. Can only be called by the current owner.
    • NOTE: Renouncing ownership will leave the contract without an owner,
    • thereby removing any functionality that is only available to the owner.
      */
      function renounceOwnership() public onlyOwner {
      emit OwnershipTransferred(_owner, address(0));
      _owner = 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 onlyOwner {
      _transferOwnership(newOwner);
      }

    /**

    • @dev Transfers ownership of the contract to a new account (newOwner).
      */
      function _transferOwnership(address newOwner) internal {
      require(newOwner != address(0), 'Ownable: new owner is the zero address');
      emit OwnershipTransferred(_owner, newOwner);
      _owner = newOwner;
      }
      }

interface IBEP20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);

/**
 * @dev Returns the token decimals.
 */
function decimals() external view returns (uint8);

/**
 * @dev Returns the token symbol.
 */
function symbol() external view returns (string memory);

/**
 * @dev Returns the token name.
 */
function name() external view returns (string memory);

/**
 * @dev Returns the bep token owner.
 */
function getOwner() external view returns (address);

/**
 * @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 `recipient`.
 *
 * Returns a boolean value indicating whether the operation succeeded.
 *
 * Emits a {Transfer} event.
 */
function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
    address recipient,
    uint256 amount
) external returns (bool);

/**
 * @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 Wrappers over Solidity's arithmetic operations with added overflow

  • checks.

  • Arithmetic operations in Solidity wrap on overflow. This can easily result

  • in bugs, because programmers usually assume that an overflow raises an

  • error, which is the standard behavior in high level programming languages.

  • SafeMath restores this intuition by reverting the transaction when an

  • operation overflows.

  • Using this library instead of the unchecked operations eliminates an entire

  • class of bugs, so it's recommended to use it always.
    /
    library SafeMath {
    /
    *

    • @dev Returns the addition of two unsigned integers, reverting on

    • overflow.

    • Counterpart to Solidity's + operator.

    • Requirements:

      • Addition cannot overflow.
        */
        function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, 'SafeMath: addition overflow');

      return c;
      }

    /**

    • @dev Returns the subtraction of two unsigned integers, reverting on
    • overflow (when the result is negative).
    • Counterpart to Solidity's - operator.
    • Requirements:
      • Subtraction cannot overflow.
        */
        function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, 'SafeMath: subtraction overflow');
        }

    /**

    • @dev Returns the subtraction of two unsigned integers, reverting with custom message on

    • overflow (when the result is negative).

    • Counterpart to Solidity's - operator.

    • Requirements:

      • Subtraction cannot overflow.
        */
        function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
        ) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

      return c;
      }

    /**

    • @dev Returns the multiplication of two unsigned integers, reverting on

    • overflow.

    • Counterpart to Solidity's * operator.

    • Requirements:

      • Multiplication cannot overflow.
        */
        function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: OpenZeppelin/openzeppelin-contracts#522
        if (a == 0) {
        return 0;
        }

      uint256 c = a * b;
      require(c / a == b, 'SafeMath: multiplication overflow');

      return c;
      }

    /**

    • @dev Returns the integer division of two unsigned integers. Reverts on
    • division by zero. The result is rounded towards zero.
    • Counterpart to Solidity's / operator. Note: this function uses a
    • revert opcode (which leaves remaining gas untouched) while Solidity
    • uses an invalid opcode to revert (consuming all remaining gas).
    • Requirements:
      • The divisor cannot be zero.
        */
        function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, 'SafeMath: division by zero');
        }

    /**

    • @dev Returns the integer division of two unsigned integers. Reverts with custom message on

    • division by zero. The result is rounded towards zero.

    • Counterpart to Solidity's / operator. Note: this function uses a

    • revert opcode (which leaves remaining gas untouched) while Solidity

    • uses an invalid opcode to revert (consuming all remaining gas).

    • Requirements:

      • The divisor cannot be zero.
        */
        function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
        ) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

      return c;
      }

    /**

    • @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
    • Reverts when dividing by zero.
    • Counterpart to Solidity's % operator. This function uses a revert
    • opcode (which leaves remaining gas untouched) while Solidity uses an
    • invalid opcode to revert (consuming all remaining gas).
    • Requirements:
      • The divisor cannot be zero.
        */
        function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, 'SafeMath: modulo by zero');
        }

    /**

    • @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
    • Reverts with custom message when dividing by zero.
    • Counterpart to Solidity's % operator. This function uses a revert
    • opcode (which leaves remaining gas untouched) while Solidity uses an
    • invalid opcode to revert (consuming all remaining gas).
    • Requirements:
      • The divisor cannot be zero.
        */
        function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
        ) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
        }

    function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
    z = x < y ? x : y;
    }

    // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
    if (y > 3) {
    z = y;
    uint256 x = y / 2 + 1;
    while (x < z) {
    z = x;
    x = (y / x + x) / 2;
    }
    } else if (y != 0) {
    z = 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
    • ====
      */
      function isContract(address account) internal view returns (bool) {
      // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
      // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
      // for accounts without code, i.e. keccak256('')
      bytes32 codehash;
      bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
      // solhint-disable-next-line no-inline-assembly
      assembly {
      codehash := extcodehash(account)
      }
      return (codehash != accountHash && codehash != 0x0);
      }

    /**

    /**

    • @dev Performs a Solidity function call using a low level call. A
    • plaincall 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 functionCall(target, data, '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');
      return _functionCallWithValue(target, data, value, errorMessage);
      }

    function _functionCallWithValue(
    address target,
    bytes memory data,
    uint256 weiValue,
    string memory errorMessage
    ) private returns (bytes memory) {
    require(isContract(target), 'Address: call to non-contract');

     // solhint-disable-next-line avoid-low-level-calls
     (bool success, bytes memory returndata) = target.call{value: weiValue}(data);
     if (success) {
         return returndata;
     } else {
         // 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
    
             // solhint-disable-next-line no-inline-assembly
             assembly {
                 let returndata_size := mload(returndata)
                 revert(add(32, returndata), returndata_size)
             }
         } else {
             revert(errorMessage);
         }
     }
    

    }
    }

/**

  • @dev Implementation of the {IBEP20} 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 {BEP20PresetMinterPauser}.

  • TIP: For a detailed writeup see our guide

  • https://forum.zeppelin.solutions/t/how-to-implement-BEP20-supply-mechanisms/226[How

  • to implement supply mechanisms].

  • We have followed general OpenZeppelin guidelines: functions revert instead

  • of returning false on failure. This behavior is nonetheless conventional

  • and does not conflict with the expectations of BEP20 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 {IBEP20-approve}.
    */
    contract BEP20 is Context, IBEP20, Ownable {
    using SafeMath for uint256;
    using Address for address;

    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**

    • @dev Sets the values for {name} and {symbol}, initializes {decimals} with
    • a default value of 18.
    • To select a different value for {decimals}, use {_setupDecimals}.
    • All three of these values are immutable: they can only be set once during
    • construction.
      */
      constructor(string memory name, string memory symbol) public {
      _name = name;
      _symbol = symbol;
      _decimals = 18;
      }

    /**

    • @dev Returns the bep token owner.
      */
      function getOwner() external override view returns (address) {
      return owner();
      }

    /**

    • @dev Returns the token name.
      */
      function name() public override view returns (string memory) {
      return _name;
      }

    /**

    • @dev Returns the token decimals.
      */
      function decimals() public override view returns (uint8) {
      return _decimals;
      }

    /**

    • @dev Returns the token symbol.
      */
      function symbol() public override view returns (string memory) {
      return _symbol;
      }

    /**

    • @dev See {BEP20-totalSupply}.
      */
      function totalSupply() public override view returns (uint256) {
      return _totalSupply;
      }

    /**

    • @dev See {BEP20-balanceOf}.
      */
      function balanceOf(address account) public override view returns (uint256) {
      return _balances[account];
      }

    /**

    • @dev See {BEP20-transfer}.
    • Requirements:
      • recipient cannot be the zero address.
      • the caller must have a balance of at least amount.
        */
        function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
        }

    /**

    • @dev See {BEP20-allowance}.
      */
      function allowance(address owner, address spender) public override view returns (uint256) {
      return _allowances[owner][spender];
      }

    /**

    • @dev See {BEP20-approve}.
    • Requirements:
      • spender cannot be the zero address.
        */
        function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
        }

    /**

    • @dev See {BEP20-transferFrom}.
    • Emits an {Approval} event indicating the updated allowance. This is not
    • required by the EIP. See the note at the beginning of {BEP20};
    • Requirements:
      • sender and recipient cannot be the zero address.
      • sender must have a balance of at least amount.
      • the caller must have allowance for sender's tokens of at least
    • amount.
      */
      function transferFrom(
      address sender,
      address recipient,
      uint256 amount
      ) public override returns (bool) {
      _transfer(sender, recipient, amount);
      _approve(
      sender,
      _msgSender(),
      _allowances[sender][_msgSender()].sub(amount, 'BEP20: transfer amount exceeds allowance')
      );
      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 {BEP20-approve}.
    • Emits an {Approval} event indicating the updated allowance.
    • Requirements:
      • spender cannot be the zero address.
        */
        function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(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 {BEP20-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 returns (bool) {
      _approve(
      _msgSender(),
      spender,
      _allowances[_msgSender()][spender].sub(subtractedValue, 'BEP20: decreased allowance below zero')
      );
      return true;
      }

    /**

    • @dev Creates amount tokens and assigns them to msg.sender, increasing
    • the total supply.
    • Requirements
      • msg.sender must be the token owner
        */
        function mint(uint256 amount) public onlyOwner returns (bool) {
        _mint(_msgSender(), amount);
        return true;
        }

    /**

    • @dev Moves tokens amount from sender to recipient.

    • This is 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:

      • sender cannot be the zero address.
      • recipient cannot be the zero address.
      • sender must have a balance of at least amount.
        */
        function _transfer(
        address sender,
        address recipient,
        uint256 amount
        ) internal {
        require(sender != address(0), 'BEP20: transfer from the zero address');
        require(recipient != address(0), 'BEP20: transfer to the zero address');

      _balances[sender] = _balances[sender].sub(amount, 'BEP20: transfer amount exceeds balance');
      _balances[recipient] = _balances[recipient].add(amount);
      emit Transfer(sender, recipient, 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

      • to cannot be the zero address.
        */
        function _mint(address account, uint256 amount) internal {
        require(account != address(0), 'BEP20: mint to the zero address');

      _totalSupply = _totalSupply.add(amount);
      _balances[account] = _balances[account].add(amount);
      emit Transfer(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 {
        require(account != address(0), 'BEP20: burn from the zero address');

      _balances[account] = _balances[account].sub(amount, 'BEP20: burn amount exceeds balance');
      _totalSupply = _totalSupply.sub(amount);
      emit Transfer(account, address(0), amount);
      }

    /**

    • @dev Sets amount as the allowance of spender over the owners tokens.

    • This is 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 {
        require(owner != address(0), 'BEP20: approve from the zero address');
        require(spender != address(0), 'BEP20: approve to the zero address');

      _allowances[owner][spender] = amount;
      emit Approval(owner, spender, amount);
      }

    /**

    • @dev Destroys amount tokens from account.amount is then deducted
    • from the caller's allowance.
    • See {_burn} and {_approve}.
      */
      function _burnFrom(address account, uint256 amount) internal {
      _burn(account, amount);
      _approve(
      account,
      _msgSender(),
      _allowances[account][_msgSender()].sub(amount, 'BEP20: burn amount exceeds allowance')
      );
      }
      }

/*


| _ )_ _ _ _ _ _ _ _ | | | |
| _ \ || | ' | ' \ || | || ||
|/_,||||||_, | () ()
|__/

  • MIT License
  • ===========
  • Copyright (c) 2020 BunnyFinance
  • Permission is hereby granted, free of charge, to any person obtaining a copy
  • of this software and associated documentation files (the "Software"), to deal
  • in the Software without restriction, including without limitation the rights
  • to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  • copies of the Software, and to permit persons to whom the Software is
  • furnished to do so, subject to the following conditions:
  • The above copyright notice and this permission notice shall be included in all
  • copies or substantial portions of the Software.
  • THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  • IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  • FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  • AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  • LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  • OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    */

// BunnyToken with Governance.
contract BunnyToken is BEP20('Bunny Token', 'BUNNY') {
/// @notice Creates _amount token to _to. Must only be called by the owner (MasterChef).
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
}

// Copied and modified from YAM code:
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
// Which is copied and modified from COMPOUND:
// https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol

/// @notice A record of each accounts delegate
mapping (address => address) internal _delegates;

/// @notice A checkpoint for marking number of votes from a given block
struct Checkpoint {
    uint32 fromBlock;
    uint256 votes;
}

/// @notice A record of votes checkpoints for each account, by index
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;

/// @notice The number of checkpoints for each account
mapping (address => uint32) public numCheckpoints;

/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");

/// @notice The EIP-712 typehash for the delegation struct used by the contract
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");

/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;

/// @notice An event thats emitted when an account changes its delegate
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);

/// @notice An event thats emitted when a delegate account's vote balance changes
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);

/**
 * @notice Delegate votes from `msg.sender` to `delegatee`
 * @param delegator The address to get delegatee for
 */
function delegates(address delegator)
external
view
returns (address)
{
    return _delegates[delegator];
}

/**
 * @notice Delegate votes from `msg.sender` to `delegatee`
 * @param delegatee The address to delegate votes to
 */
function delegate(address delegatee) external {
    return _delegate(msg.sender, delegatee);
}

/**
 * @notice Delegates votes from signatory to `delegatee`
 * @param delegatee The address to delegate votes to
 * @param nonce The contract state required to match the signature
 * @param expiry The time at which to expire the signature
 * @param v The recovery byte of the signature
 * @param r Half of the ECDSA signature pair
 * @param s Half of the ECDSA signature pair
 */
function delegateBySig(
    address delegatee,
    uint nonce,
    uint expiry,
    uint8 v,
    bytes32 r,
    bytes32 s
)
external
{
    bytes32 domainSeparator = keccak256(
        abi.encode(
            DOMAIN_TYPEHASH,
            keccak256(bytes(name())),
            getChainId(),
            address(this)
        )
    );

    bytes32 structHash = keccak256(
        abi.encode(
            DELEGATION_TYPEHASH,
            delegatee,
            nonce,
            expiry
        )
    );

    bytes32 digest = keccak256(
        abi.encodePacked(
            "\x19\x01",
            domainSeparator,
            structHash
        )
    );

    address signatory = ecrecover(digest, v, r, s);
    require(signatory != address(0), "BUNNY::delegateBySig: invalid signature");
    require(nonce == nonces[signatory]++, "BUNNY::delegateBySig: invalid nonce");
    require(now <= expiry, "BUNNY::delegateBySig: signature expired");
    return _delegate(signatory, delegatee);
}

/**
 * @notice Gets the current votes balance for `account`
 * @param account The address to get votes balance
 * @return The number of current votes for `account`
 */
function getCurrentVotes(address account)
external
view
returns (uint256)
{
    uint32 nCheckpoints = numCheckpoints[account];
    return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}

/**
 * @notice Determine the prior number of votes for an account as of a block number
 * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
 * @param account The address of the account to check
 * @param blockNumber The block number to get the vote balance at
 * @return The number of votes the account had as of the given block
 */
function getPriorVotes(address account, uint blockNumber)
external
view
returns (uint256)
{
    require(blockNumber < block.number, "BUNNY::getPriorVotes: not yet determined");

    uint32 nCheckpoints = numCheckpoints[account];
    if (nCheckpoints == 0) {
        return 0;
    }

    // First check most recent balance
    if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
        return checkpoints[account][nCheckpoints - 1].votes;
    }

    // Next check implicit zero balance
    if (checkpoints[account][0].fromBlock > blockNumber) {
        return 0;
    }

    uint32 lower = 0;
    uint32 upper = nCheckpoints - 1;
    while (upper > lower) {
        uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
        Checkpoint memory cp = checkpoints[account][center];
        if (cp.fromBlock == blockNumber) {
            return cp.votes;
        } else if (cp.fromBlock < blockNumber) {
            lower = center;
        } else {
            upper = center - 1;
        }
    }
    return checkpoints[account][lower].votes;
}

function _delegate(address delegator, address delegatee)
internal
{
    address currentDelegate = _delegates[delegator];
    uint256 delegatorBalance = balanceOf(delegator); // balance of underlying BUNNYs (not scaled);
    _delegates[delegator] = delegatee;

    emit DelegateChanged(delegator, currentDelegate, delegatee);

    _moveDelegates(currentDelegate, delegatee, delegatorBalance);
}

function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
    if (srcRep != dstRep && amount > 0) {
        if (srcRep != address(0)) {
            // decrease old representative
            uint32 srcRepNum = numCheckpoints[srcRep];
            uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
            uint256 srcRepNew = srcRepOld.sub(amount);
            _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
        }

        if (dstRep != address(0)) {
            // increase new representative
            uint32 dstRepNum = numCheckpoints[dstRep];
            uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
            uint256 dstRepNew = dstRepOld.add(amount);
            _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
        }
    }
}

function _writeCheckpoint(
    address delegatee,
    uint32 nCheckpoints,
    uint256 oldVotes,
    uint256 newVotes
)
internal
{
    uint32 blockNumber = safe32(block.number, "BUNNY::_writeCheckpoint: block number exceeds 32 bits");

    if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
        checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
    } else {
        checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
        numCheckpoints[delegatee] = nCheckpoints + 1;
    }

    emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}

function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
    require(n < 2**32, errorMessage);
    return uint32(n);
}

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

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.