Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0x020eb84309243Ed4B8E6C197AF145125dDE4AFDa
Balance 0 ETH
Nonce 1
Code Size 6663 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

6663 bytes
0x6080604052600436106101955763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301681a62811461019a57806306fdde03146101bd578063095ea7b31461024757806313ca42e81461027f5780631624f6c6146102a957806318160ddd1461034557806323b872dd1461035a578063313ce5671461038457806339509351146103af5780633a98ef39146103d35780635d2dde1d146103e85780636f97854c146104005780636fafb2361461041557806370a082311461042d578063715018a61461044e578063786ffeb8146104635780637a43e23f146104785780638b5a6a08146104935780638da5cb5b146104b45780638e27d7d7146104e55780638f32d59b146104fa57806395d89b411461050f578063a457c2d714610524578063a9059cbb14610548578063b8fd8e731461056c578063bc02f3f714610581578063c4d66de814610596578063dd62ed3e146105b7578063f2301efa146105de578063f2fde38b146105f3578063f5eb42dc14610614578063fb334b5514610635575b600080fd5b3480156101a657600080fd5b506101bb600160a060020a036004351661064d565b005b3480156101c957600080fd5b506101d26107f7565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561020c5781810151838201526020016101f4565b50505050905090810190601f1680156102395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561025357600080fd5b5061026b600160a060020a036004351660243561088e565b604080519115158252519081900360200190f35b34801561028b57600080fd5b506102976004356108f5565b60408051918252519081900360200190f35b3480156102b557600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101bb94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497505050923560ff16935061091492505050565b34801561035157600080fd5b50610297610a36565b34801561036657600080fd5b5061026b600160a060020a0360043581169060243516604435610a3c565b34801561039057600080fd5b50610399610b89565b6040805160ff9092168252519081900360200190f35b3480156103bb57600080fd5b5061026b600160a060020a0360043516602435610b92565b3480156103df57600080fd5b50610297610c2b565b3480156103f457600080fd5b50610297600435610c36565b34801561040c57600080fd5b50610297610c5b565b34801561042157600080fd5b50610297600435610c61565b34801561043957600080fd5b50610297600160a060020a0360043516610c9c565b34801561045a57600080fd5b506101bb610cca565b34801561046f57600080fd5b506101bb610d34565b34801561048457600080fd5b50610297600435602435610d94565b34801561049f57600080fd5b506101bb600160a060020a0360043516610f3a565b3480156104c057600080fd5b506104c9610fae565b60408051600160a060020a039092168252519081900360200190f35b3480156104f157600080fd5b506104c9610fbd565b34801561050657600080fd5b5061026b610fcc565b34801561051b57600080fd5b506101d2610fdd565b34801561053057600080fd5b5061026b600160a060020a036004351660243561103e565b34801561055457600080fd5b5061026b600160a060020a036004351660243561112f565b34801561057857600080fd5b50610297611215565b34801561058d57600080fd5b5061029761121b565b3480156105a257600080fd5b506101bb600160a060020a0360043516611221565b3480156105c357600080fd5b50610297600160a060020a0360043581169060243516611423565b3480156105ea57600080fd5b506101bb61144e565b3480156105ff57600080fd5b506101bb600160a060020a03600435166115d2565b34801561062057600080fd5b50610297600160a060020a03600435166115ee565b34801561064157600080fd5b50610297600435611609565b610655610fcc565b151561066057600080fd5b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600091600160a060020a038416916370a082319160248082019260209290919082900301818787803b1580156106c457600080fd5b505af11580156106d8573d6000803e3d6000fd5b505050506040513d60208110156106ee57600080fd5b505111610745576040805160e560020a62461bcd02815260206004820152601360248201527f4e6f2062616c616e636520746f20737765657000000000000000000000000000604482015290519081900360640190fd5b6107f4610750610fae565b604080517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529051600160a060020a038516916370a082319160248083019260209291908290030181600087803b1580156107b157600080fd5b505af11580156107c5573d6000803e3d6000fd5b505050506040513d60208110156107db57600080fd5b5051600160a060020a038416919063ffffffff61162816565b50565b60338054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108835780601f1061085857610100808354040283529160200191610883565b820191906000526020600020905b81548152906001019060200180831161086657829003601f168201915b505050505090505b90565b33600081815260a260209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b600061090c609f54836116e090919063ffffffff16565b90505b919050565b60008054610100900460ff168061092e575061092e611715565b8061093c575060005460ff16155b15156109b8576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560448201527f656e20696e697469616c697a6564000000000000000000000000000000000000606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff191691909117909255845191900460ff16906109ef90603390602087019061192d565b508251610a0390603490602086019061192d565b506035805460ff90931660ff1990931692909217909155600080549115156101000261ff00199092169190911790555050565b609e5490565b60008083600160a060020a0381161515610a5557600080fd5b600160a060020a038116301415610a6b57600080fd5b600160a060020a038616600090815260a260209081526040808320338452909152902054610a9f908563ffffffff61171f16565b600160a060020a038716600090815260a260209081526040808320338452909152902055609f54610ad790859063ffffffff6116e016565b600160a060020a038716600090815260a16020526040902054909250610b03908363ffffffff61171f16565b600160a060020a03808816600090815260a160205260408082209390935590871681522054610b38908363ffffffff61173616565b600160a060020a03808716600081815260a1602090815260409182902094909455805188815290519193928a16926000805160206119bc83398151915292918290030190a350600195945050505050565b60355460ff1690565b33600090815260a260209081526040808320600160a060020a0386168452909152812054610bc6908363ffffffff61173616565b33600081815260a260209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b65038f18b3bfff1990565b6000811515610c475750600061090f565b609f5461090c90839063ffffffff61174816565b609f5481565b6000811515610c725750600061090f565b60a05461090c90633b9aca0090610c9090859063ffffffff61174816565b9063ffffffff6116e016565b609f54600160a060020a038216600090815260a16020526040812054909161090c919063ffffffff61174816565b610cd2610fcc565b1515610cdd57600080fd5b606854604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a26068805473ffffffffffffffffffffffffffffffffffffffff19169055565b610d3c610fcc565b1515610d4757600080fd5b609d805460ff19811660ff918216151791829055604080519290911615158252517f5a0bf9e319608025595c307982a11f298457c9efa231f2b37db72f907681bf509181900360200190a1565b609b54600090600160a060020a03163314610dae57600080fd5b609c54421015610dbd57600080fd5b609d5460ff1615610e18576040805160e560020a62461bcd02815260206004820152600d60248201527f5265626173652070617573656400000000000000000000000000000000000000604482015290519081900360640190fd5b811515610e6057609e54604080519182525184917f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f2919081900360200190a250609e546108ef565b6000821215610e8c57610e84610e758361176b565b609e549063ffffffff61171f16565b609e55610ea3565b609e54610e9f908363ffffffff61173616565b609e555b609e546fffffffffffffffffffffffffffffffff1015610ed2576fffffffffffffffffffffffffffffffff609e555b609e54610ef5906503a3529440006000195b06600019039063ffffffff61174816565b609f55609e54604080519182525184917f72725a3b1e5bd622d6bcd1339bb31279c351abe8f541ac7fd320f24e1b1641f2919081900360200190a250609e5492915050565b610f42610fcc565b1515610f4d57600080fd5b609b8054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f0e6961f1a1afb87eaf51fd64f22ddc10062e23aa7838eac5d0bdf140bfd389729181900360200190a150565b606854600160a060020a031690565b609b54600160a060020a031681565b606854600160a060020a0316331490565b60348054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156108835780601f1061085857610100808354040283529160200191610883565b33600090815260a260209081526040808320600160a060020a03861684529091528120548083106110925733600090815260a260209081526040808320600160a060020a03881684529091528120556110c7565b6110a2818463ffffffff61171f16565b33600090815260a260209081526040808320600160a060020a03891684529091529020555b33600081815260a260209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a3600191505b5092915050565b60008083600160a060020a038116151561114857600080fd5b600160a060020a03811630141561115e57600080fd5b609f5461117290859063ffffffff6116e016565b33600090815260a16020526040902054909250611195908363ffffffff61171f16565b33600090815260a1602052604080822092909255600160a060020a038716815220546111c7908363ffffffff61173616565b600160a060020a038616600081815260a160209081526040918290209390935580518781529051919233926000805160206119bc8339815191529281900390910190a3506001949350505050565b609c5481565b60a05481565b60008054610100900460ff168061123b575061123b611715565b80611249575060005460ff16155b15156112c5576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560448201527f656e20696e697469616c697a6564000000000000000000000000000000000000606482015290519081900360840190fd5b5060008054600161010061ff00198316811760ff19169190911790925560408051808201825260048082527f446967670000000000000000000000000000000000000000000000000000000060208084019190915283518085019094529083527f4449474700000000000000000000000000000000000000000000000000000000908301529290910460ff169161135d916009610914565b611366826117af565b6000609c819055609d8054600160ff199091161761ff00191690556503a352944000609e818155600160a060020a038516835260a1602052604090922065038f18b3bfff19905590546113bb91600019610ee4565b609f55609e546113d4906503a352944000600019610ee4565b60a055609e546040805191825251600160a060020a038416916000916000805160206119bc8339815191529181900360200190a3600080549115156101000261ff001990921691909117905550565b600160a060020a03918216600090815260a26020908152604080832093909416825291909152205490565b6000611458610fcc565b151561146357600080fd5b60a35460ff16156114be576040805160e560020a62461bcd02815260206004820152601560248201527f4d696e7420616c726561647920636f6d706c6574650000000000000000000000604482015290519081900360640190fd5b609f546114d790640c53975a2c9063ffffffff6116e016565b73042b32ac6b453485e357938bdc38e0340d4b927660005260a16020527fb11151bac19ff8fc7e34b8fd6da52adb275a3c3e278bfd9026d41262ebb1b5bf54909150611529908263ffffffff61173616565b73042b32ac6b453485e357938bdc38e0340d4b927660005260a16020527fb11151bac19ff8fc7e34b8fd6da52adb275a3c3e278bfd9026d41262ebb1b5bf55609e5461158090640c53975a2c63ffffffff61173616565b609e5560a3805460ff1916600117905560408051640c53975a2c8152905173042b32ac6b453485e357938bdc38e0340d4b9276916000916000805160206119bc8339815191529181900360200190a350565b6115da610fcc565b15156115e557600080fd5b6107f4816118af565b600160a060020a0316600090815260a1602052604090205490565b600061090c6009600a0a610c9060a054856116e090919063ffffffff16565b82600160a060020a031663a9059cbb83836040518363ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050602060405180830381600087803b1580156116a457600080fd5b505af11580156116b8573d6000803e3d6000fd5b505050506040513d60208110156116ce57600080fd5b505115156116db57600080fd5b505050565b6000808315156116f35760009150611128565b5082820282848281151561170357fe5b041461170e57600080fd5b9392505050565b303b8015905b5090565b6000808383111561172f57600080fd5b5050900390565b60008282018381101561170e57600080fd5b60008080831161175757600080fd5b828481151561176257fe5b04949350505050565b60007f800000000000000000000000000000000000000000000000000000000000000082141561179a57600080fd5b600082126117a8578161090c565b5060000390565b60008054610100900460ff16806117c957506117c9611715565b806117d7575060005460ff16155b1515611853576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560448201527f656e20696e697469616c697a6564000000000000000000000000000000000000606482015290519081900360840190fd5b50600080546068805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03949094169390931790925561ff001980831661010090811760ff19166001179091169281900460ff16151502919091179055565b600160a060020a03811615156118c457600080fd5b606854604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a36068805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061196e57805160ff191683800117855561199b565b8280016001018555821561199b579182015b8281111561199b578251825591602001919060010190611980565b5061171b9261088b9250905b8082111561171b57600081556001016119a75600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a7230582072dacf22200b066ec4b6b216902761eddaaf2876c714ff7f831bb7c5cc41dabc0029

Verified Source Code Partial Match

Compiler: v0.4.24+commit.e67f0147 EVM: byzantium Optimization: Yes (200 runs)
UFragments.sol 747 lines
// SPDX-License-Identifier: NONE

pragma solidity 0.4.24;



// Part: IERC20

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
interface IERC20 {
  function totalSupply() external view returns (uint256);

  function balanceOf(address who) external view returns (uint256);

  function allowance(address owner, address spender)
    external view returns (uint256);

  function transfer(address to, uint256 value) external returns (bool);

  function approve(address spender, uint256 value)
    external returns (bool);

  function transferFrom(address from, address to, uint256 value)
    external returns (bool);

  event Transfer(
    address indexed from,
    address indexed to,
    uint256 value
  );

  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

// Part: Initializable

/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool wasInitializing = initializing;
    initializing = true;
    initialized = true;

    _;

    initializing = wasInitializing;
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    uint256 cs;
    assembly { cs := extcodesize(address) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// Part: SafeMath

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, reverts on 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: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}

// Part: SafeMathInt

/**
 * @title SafeMathInt
 * @dev Math operations for int256 with overflow safety checks.
 */
library SafeMathInt {
    int256 private constant MIN_INT256 = int256(1) << 255;
    int256 private constant MAX_INT256 = ~(int256(1) << 255);

    /**
     * @dev Multiplies two int256 variables and fails on overflow.
     */
    function mul(int256 a, int256 b)
        internal
        pure
        returns (int256)
    {
        int256 c = a * b;

        // Detect overflow when multiplying MIN_INT256 with -1
        require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
        require((b == 0) || (c / b == a));
        return c;
    }

    /**
     * @dev Division of two int256 variables and fails on overflow.
     */
    function div(int256 a, int256 b)
        internal
        pure
        returns (int256)
    {
        // Prevent overflow when dividing MIN_INT256 by -1
        require(b != -1 || a != MIN_INT256);

        // Solidity already throws when dividing by 0.
        return a / b;
    }

    /**
     * @dev Subtracts two int256 variables and fails on overflow.
     */
    function sub(int256 a, int256 b)
        internal
        pure
        returns (int256)
    {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a));
        return c;
    }

    /**
     * @dev Adds two int256 variables and fails on overflow.
     */
    function add(int256 a, int256 b)
        internal
        pure
        returns (int256)
    {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a));
        return c;
    }

    /**
     * @dev Converts to absolute value, and fails on overflow.
     */
    function abs(int256 a)
        internal
        pure
        returns (int256)
    {
        require(a != MIN_INT256);
        return a < 0 ? -a : a;
    }
}

// Part: ERC20Detailed

/**
 * @title ERC20Detailed token
 * @dev The decimals are only for visualization purposes.
 * All the operations are done using the smallest and indivisible token unit,
 * just as on Ethereum all the operations are done in wei.
 */
contract ERC20Detailed is Initializable, IERC20 {
  string private _name;
  string private _symbol;
  uint8 private _decimals;

  function initialize(string name, string symbol, uint8 decimals) public initializer {
    _name = name;
    _symbol = symbol;
    _decimals = decimals;
  }

  /**
   * @return the name of the token.
   */
  function name() public view returns(string) {
    return _name;
  }

  /**
   * @return the symbol of the token.
   */
  function symbol() public view returns(string) {
    return _symbol;
  }

  /**
   * @return the number of decimals of the token.
   */
  function decimals() public view returns(uint8) {
    return _decimals;
  }

  uint256[50] private ______gap;
}

// Part: Ownable

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable is Initializable {
  address private _owner;


  event OwnershipRenounced(address indexed previousOwner);
  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function initialize(address sender) public initializer {
    _owner = sender;
  }

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

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(isOwner());
    _;
  }

  /**
   * @return true if `msg.sender` is the owner of the contract.
   */
  function isOwner() public view returns(bool) {
    return msg.sender == _owner;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(_owner);
    _owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    _transferOwnership(newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address newOwner) internal {
    require(newOwner != address(0));
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }

  uint256[50] private ______gap;
}

// Part: SafeERC20

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
  function safeTransfer(
    IERC20 token,
    address to,
    uint256 value
  )
    internal
  {
    require(token.transfer(to, value));
  }

  function safeTransferFrom(
    IERC20 token,
    address from,
    address to,
    uint256 value
  )
    internal
  {
    require(token.transferFrom(from, to, value));
  }

  function safeApprove(
    IERC20 token,
    address spender,
    uint256 value
  )
    internal
  {
    require(token.approve(spender, value));
  }
}

// File: UFragments.sol

/**
 * @title uFragments ERC20 token
 * @dev This is part of an implementation of the uFragments Ideal Money protocol.
 *      uFragments is a normal ERC20 token, but its supply can be adjusted by splitting and
 *      combining tokens proportionally across all wallets.
 *
 *      uFragment balances are internally represented with a hidden denomination, 'shares'.
 *      We support splitting the currency in expansion and combining the currency on contraction by
 *      changing the exchange rate between the hidden 'shares' and the public 'fragments'.
 */

contract UFragments is ERC20Detailed, Ownable {
    // PLEASE READ BEFORE CHANGING ANY ACCOUNTING OR MATH
    // Anytime there is division, there is a risk of numerical instability from rounding errors. In
    // order to minimize this risk, we adhere to the following guidelines:
    // 1) The conversion rate adopted is the number of shares that equals 1 fragment.
    //    The inverse rate must not be used--TOTAL_SHARES is always the numerator and _totalSupply is
    //    always the denominator. (i.e. If you want to convert shares to fragments instead of
    //    multiplying by the inverse rate, you should divide by the normal rate)
    // 2) Share balances converted into Fragments are always rounded down (truncated).
    //
    // We make the following guarantees:
    // - If address 'A' transfers x Fragments to address 'B'. A's resulting external balance will
    //   be decreased by precisely x Fragments, and B's external balance will be precisely
    //   increased by x Fragments.
    //
    // We do not guarantee that the sum of all balances equals the result of calling totalSupply().
    // This is because, for any conversion function 'f()' that has non-zero rounding error,
    // f(x0) + f(x1) + ... + f(xn) is not always equal to f(x0 + x1 + ... xn).
    using SafeMath for uint256;
    using SafeMathInt for int256;
    using SafeERC20 for IERC20;

    event LogRebase(uint256 indexed epoch, uint256 totalSupply);
    event LogMonetaryPolicyUpdated(address monetaryPolicy);
    event RebaseToggled(bool rebasePaused);

    // Used for authentication
    address public monetaryPolicy;
    uint256 public rebaseStartTime;

    modifier onlyMonetaryPolicy() {
        require(msg.sender == monetaryPolicy);
        _;
    }

    // Reactivated rebasePaused flag per BIP92 (https://forum.badger.finance/t/bip-92-digg-restructuring-v3-revised/5653)
    bool private rebasePaused;
    bool private tokenPausedDeprecated;

    modifier validRecipient(address to) {
        require(to != address(0x0));
        require(to != address(this));
        _;
    }

    modifier onlyAfterRebaseStart() {
        require(now >= rebaseStartTime);
        _;
    }

    uint256 private constant DECIMALS = 9;
    uint256 private constant SCALED_SHARES_EXTRA_DECIMALS = 9;
    uint256 private constant MAX_UINT256 = ~uint256(0);
    uint256 private constant MAX_UINT128 = ~uint128(0);
    uint256 private constant MAX_FRAGMENTS_SUPPLY = 4000 * 10**DECIMALS;

    // TOTAL_SHARES is a multiple of MAX_FRAGMENTS_SUPPLY so that _sharesPerFragment is an integer.
    // Use the highest value that fits in a uint128 for sufficient granularity.
    uint256 private constant TOTAL_SHARES = MAX_UINT256 - (MAX_UINT256 % MAX_FRAGMENTS_SUPPLY);

    // MAX_SUPPLY = maximum integer < (sqrt(4*TOTAL_SHARES + 1) - 1) / 2
    uint256 private constant MAX_SUPPLY = MAX_UINT128;

    uint256 private _totalSupply;
    uint256 public _sharesPerFragment;
    uint256 public _initialSharesPerFragment;
    mapping(address => uint256) private _shareBalances;

    // This is denominated in Fragments, because the shares-fragments conversion might change before
    // it's fully paid.
    mapping(address => mapping(address => uint256)) private _allowedFragments;

    // Data for minting remDIGG
    address private constant TREASURY_OPS_MSIG = 0x042B32Ac6b453485e357938bdC38e0340d4b9276;
    uint256 private constant MINT_AMOUNT = 52942035500;
    bool private remDiggMint;

    /**
     * @param monetaryPolicy_ The address of the monetary policy contract to use for authentication.
     */
    function setMonetaryPolicy(address monetaryPolicy_) external onlyOwner {
        monetaryPolicy = monetaryPolicy_;
        emit LogMonetaryPolicyUpdated(monetaryPolicy_);
    }

    /**
     * @dev Notifies Fragments contract about a new rebase cycle.
     * @param supplyDelta The number of new fragment tokens to add into circulation via expansion.
     * @return The total number of fragments after the supply adjustment.
     */
    function rebase(uint256 epoch, int256 supplyDelta) external onlyMonetaryPolicy onlyAfterRebaseStart returns (uint256) {
        require(!rebasePaused, "Rebase paused");

        if (supplyDelta == 0) {
            emit LogRebase(epoch, _totalSupply);
            return _totalSupply;
        }

        if (supplyDelta < 0) {
            _totalSupply = _totalSupply.sub(uint256(supplyDelta.abs()));
        } else {
            _totalSupply = _totalSupply.add(uint256(supplyDelta));
        }

        if (_totalSupply > MAX_SUPPLY) {
            _totalSupply = MAX_SUPPLY;
        }

        _sharesPerFragment = TOTAL_SHARES.div(_totalSupply);

        // From this point forward, _sharesPerFragment is taken as the source of truth.
        // We recalculate a new _totalSupply to be in agreement with the _sharesPerFragment
        // conversion rate.
        // This means our applied supplyDelta can deviate from the requested supplyDelta,
        // but this deviation is guaranteed to be < (_totalSupply^2)/(TOTAL_SHARES - _totalSupply).
        //
        // In the case of _totalSupply <= MAX_UINT128 (our current supply cap), this
        // deviation is guaranteed to be < 1, so we can omit this step. If the supply cap is
        // ever increased, it must be re-included.
        // NB: Digg will likely never reach the total supply cap as the total supply of BTC is
        // currently 21 million and MAX_UINT128 is many orders of magnitude greater.
        // _totalSupply = TOTAL_SHARES.div(_sharesPerFragment)

        emit LogRebase(epoch, _totalSupply);
        return _totalSupply;
    }

    function initialize(address owner_) public initializer {
        ERC20Detailed.initialize("Digg", "DIGG", uint8(DECIMALS));
        Ownable.initialize(owner_);

        rebaseStartTime = 0;
        rebasePaused = true;
        tokenPausedDeprecated = false;

        _totalSupply = MAX_FRAGMENTS_SUPPLY;
        _shareBalances[owner_] = TOTAL_SHARES;
        _sharesPerFragment = TOTAL_SHARES.div(_totalSupply);
        _initialSharesPerFragment = TOTAL_SHARES.div(_totalSupply);

        emit Transfer(address(0x0), owner_, _totalSupply);
    }

    /**
     * @return The total number of fragments.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @return The total number of underlying shares.
     */
    function totalShares() public view returns (uint256) {
        return TOTAL_SHARES;
    }

    /**
     * @param who The address to query.
     * @return The balance of the specified address.
     */
    function balanceOf(address who) public view returns (uint256) {
        return _shareBalances[who].div(_sharesPerFragment);
    }

    /**
     * @param who The address to query.
     * @return The underlying shares of the specified address.
     */
    function sharesOf(address who) public view returns (uint256) {
        return _shareBalances[who];
    }

    /**
     * @param fragments Fragment value to convert.
     * @return The underlying share value of the specified fragment amount.
     */
    function fragmentsToShares(uint256 fragments) public view returns (uint256) {
        return fragments.mul(_sharesPerFragment);
    }

    /**
     * @param shares Share value to convert.
     * @return The current fragment value of the specified underlying share amount.
     */
    function sharesToFragments(uint256 shares) public view returns (uint256) {
        if (shares == 0) {
            return 0;
        }
        return shares.div(_sharesPerFragment);
    }

    /// @dev Scaled Shares are a user-friendly representation of shares
    function scaledSharesToShares(uint256 fragments) public view returns (uint256) {
        return fragments.mul(_initialSharesPerFragment).mul(10**SCALED_SHARES_EXTRA_DECIMALS);
    }

    function sharesToScaledShares(uint256 shares) public view returns (uint256) {
        if (shares == 0) {
            return 0;
        }
        return shares.div(_initialSharesPerFragment).mul(10**SCALED_SHARES_EXTRA_DECIMALS);
    }

    /**
     * @dev Transfer tokens to a specified address.
     * @param to The address to transfer to.
     * @param value The amount to be transferred.
     * @return True on success, false otherwise.
     */
    function transfer(address to, uint256 value) public validRecipient(to) returns (bool) {
        uint256 shareValue = value.mul(_sharesPerFragment);
        _shareBalances[msg.sender] = _shareBalances[msg.sender].sub(shareValue);
        _shareBalances[to] = _shareBalances[to].add(shareValue);
        emit Transfer(msg.sender, to, value);
        return true;
    }

    /**
     * @dev Function to check the amount of tokens that an owner has allowed to a spender.
     * @param owner_ The address which owns the funds.
     * @param spender The address which will spend the funds.
     * @return The number of tokens still available for the spender.
     */
    function allowance(address owner_, address spender) public view returns (uint256) {
        return _allowedFragments[owner_][spender];
    }

    /**
     * @dev Transfer tokens from one address to another.
     * @param from The address you want to send tokens from.
     * @param to The address you want to transfer to.
     * @param value The amount of tokens to be transferred.
     */
    function transferFrom(
        address from,
        address to,
        uint256 value
    ) public validRecipient(to) returns (bool) {
        _allowedFragments[from][msg.sender] = _allowedFragments[from][msg.sender].sub(value);

        uint256 shareValue = value.mul(_sharesPerFragment);
        _shareBalances[from] = _shareBalances[from].sub(shareValue);
        _shareBalances[to] = _shareBalances[to].add(shareValue);
        emit Transfer(from, to, value);

        return true;
    }

    /**
     * @dev Approve the passed address to spend the specified amount of tokens on behalf of
     * msg.sender. This method is included for ERC20 compatibility.
     * increaseAllowance and decreaseAllowance should be used instead.
     * Changing an allowance with this method brings the risk that someone may transfer both
     * the old and the new allowance - if they are both greater than zero - if a transfer
     * transaction is mined before the later approve() call is mined.
     *
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        _allowedFragments[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    /**
     * @dev Increase the amount of tokens that an owner has allowed to a spender.
     * This method should be used instead of approve() to avoid the double approval vulnerability
     * described above.
     * @param spender The address which will spend the funds.
     * @param addedValue The amount of tokens to increase the allowance by.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _allowedFragments[msg.sender][spender] = _allowedFragments[msg.sender][spender].add(addedValue);
        emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
        return true;
    }

    /**
     * @dev Decrease the amount of tokens that an owner has allowed to a spender.
     *
     * @param spender The address which will spend the funds.
     * @param subtractedValue The amount of tokens to decrease the allowance by.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        uint256 oldValue = _allowedFragments[msg.sender][spender];
        if (subtractedValue >= oldValue) {
            _allowedFragments[msg.sender][spender] = 0;
        } else {
            _allowedFragments[msg.sender][spender] = oldValue.sub(subtractedValue);
        }
        emit Approval(msg.sender, spender, _allowedFragments[msg.sender][spender]);
        return true;
    }

    /**
     * @notice Mints the reimbursement for remDIGG one time, directly to dev multisig
     * @dev This is implemented to address BIP92 (https://forum.badger.finance/t/bip-92-digg-restructuring-v3-revised/5653)
     * @dev by allowing the development multisig a one time mint of the totalSupply of remDIGG for distribution
     */
    function oneTimeMint() external onlyOwner {
        require(!remDiggMint, "Mint already complete");
        uint256 shareValue = MINT_AMOUNT.mul(_sharesPerFragment);
        _shareBalances[TREASURY_OPS_MSIG] = _shareBalances[TREASURY_OPS_MSIG].add(shareValue);
        _totalSupply = _totalSupply.add(MINT_AMOUNT);
        remDiggMint = true;
        emit Transfer(address(0x0), TREASURY_OPS_MSIG, MINT_AMOUNT);
    }

    /**
     * @notice Sweep unprotected tokens to the owner contract to recover them from the contract
     * @param _token token to sweep from the contract
     * @dev this contract should never hold any tokens so there are no protected tokens
     */
    function sweep(IERC20 _token) external onlyOwner {
        require(_token.balanceOf(address(this)) > 0, "No balance to sweep");
        _token.safeTransfer(owner(), _token.balanceOf(address(this)));
    }

    /// @notice Toggle rebase functionality
    function toggleRebase() external onlyOwner {
        rebasePaused = !rebasePaused;
        emit RebaseToggled(rebasePaused);
    }
}

Read Contract

_initialSharesPerFragment 0xbc02f3f7 → uint256
_sharesPerFragment 0x6f97854c → uint256
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
fragmentsToShares 0x13ca42e8 → uint256
isOwner 0x8f32d59b → bool
monetaryPolicy 0x8e27d7d7 → address
name 0x06fdde03 → string
owner 0x8da5cb5b → address
rebaseStartTime 0xb8fd8e73 → uint256
scaledSharesToShares 0xfb334b55 → uint256
sharesOf 0xf5eb42dc → uint256
sharesToFragments 0x5d2dde1d → uint256
sharesToScaledShares 0x6fafb236 → uint256
symbol 0x95d89b41 → string
totalShares 0x3a98ef39 → uint256
totalSupply 0x18160ddd → uint256

Write Contract 14 functions

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

approve 0x095ea7b3
address spender
uint256 value
returns: bool
decreaseAllowance 0xa457c2d7
address spender
uint256 subtractedValue
returns: bool
increaseAllowance 0x39509351
address spender
uint256 addedValue
returns: bool
initialize 0x1624f6c6
string name
string symbol
uint8 decimals
initialize 0xc4d66de8
address owner_
oneTimeMint 0xf2301efa
No parameters
rebase 0x7a43e23f
uint256 epoch
int256 supplyDelta
returns: uint256
renounceOwnership 0x715018a6
No parameters
setMonetaryPolicy 0x8b5a6a08
address monetaryPolicy_
sweep 0x01681a62
address _token
toggleRebase 0x786ffeb8
No parameters
transfer 0xa9059cbb
address to
uint256 value
returns: bool
transferFrom 0x23b872dd
address from
address to
uint256 value
returns: bool
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address