ETH Price: $1,955.36 (-1.62%)

Transaction Decoder

Block:
9275513 at Jan-13-2020 11:02:01 PM +UTC
Transaction Fee:
0.000050984 ETH $0.10
Gas Used:
50,984 Gas / 1 Gwei

Emitted Events:

137 MainToken.Transfer( from=[Receiver] MainToken, to=[Sender] 0xface5635f93443570dd619c1b1bcea25e18e2997, value=425999042293729295 )

Account State Difference:

  Address   Before After State Difference Code
0x7c0AFD49...37d54EE7e 0.226005747441199394 Eth0.228986220695895604 Eth0.00298047325469621
199.668197701372135709 Eth199.668248685372135709 Eth0.000050984
0xFACe5635...5E18E2997
0.011675858100795681 Eth
Nonce: 94
0.008644400846099471 Eth
Nonce: 95
0.00303145725469621

Execution Trace

ETH 0.00298047325469621 MainToken.CALL( )
  • 0x075ad905949cc95ee905b02b8ba9f0fc2b742a10.STATICCALL( )
    • MainToken.assetContracts( input=0x7c0AFD49D40Ec308d49E2926E5c99B037d54EE7e ) => ( False )
    • Medianizer.STATICCALL( )
    • FiatContract.USD( _id=0 ) => ( 69163461019999 )
      File 1 of 3: MainToken
      pragma solidity ^0.5.11;
      
      library SafeMath {
      
          function add(uint256 a, uint256 b) internal pure returns (uint256) {
              uint256 c = a + b;
              require(c >= a, "SafeMath: addition overflow");
              return c;}
      
          function sub(uint256 a, uint256 b) internal pure returns (uint256) {
              return sub(a, b, "SafeMath: subtraction overflow");}
      
          function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
              require(b <= a, errorMessage);
              uint256 c = a - b;
              return c;}
      
          function mul(uint256 a, uint256 b) internal pure returns (uint256) {
              if (a == 0) {return 0;}
              uint256 c = a * b;
              require(c / a == b, "SafeMath: multiplication overflow");
              return c;}
      
          function div(uint256 a, uint256 b) internal pure returns (uint256) {
              return div(a, b, "SafeMath: division by zero");}
      
          function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
              require(b > 0, errorMessage);
              uint256 c = a / b;
              return c;}
      }
      
      contract Secondary {
          address private _primary;
          address private _primaryCandidate;
      
          constructor () internal {
              _primary = msg.sender;
              _primaryCandidate = address(0);
          }
      
          modifier onlyPrimary() {
              require(msg.sender == _primary, "Secondary: caller is not the primary account");
              _;
          }
      
          function primary() public view returns (address) {
              return _primary;
          }
          
          function acceptBeingPrimary() public {
              require(msg.sender == _primaryCandidate, "Secondary: caller is not the primary candidate account");
              require(msg.sender != address(0));
              
              _primary = _primaryCandidate;
              _primaryCandidate = address(0);
          }
      
          function setPrimaryCandidate(address recipient) public onlyPrimary {
              require(recipient != _primary);
              _primaryCandidate = recipient;
          }
      }
      
      interface IERC20 {
          function totalSupply() external view returns (uint256);
          function balanceOf(address account) external view returns (uint256);
          function transfer(address recipient, uint256 amount) external returns (bool);
          function allowance(address owner, address spender) external view returns (uint256);
          function approve(address spender, uint256 amount) external returns (bool);
          function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
          event Transfer(address indexed from, address indexed to, uint256 value);
          event Approval(address indexed owner, address indexed spender, uint256 value);
      }
      
      contract assetContractable is Secondary{
          mapping(address=>bool) private _assetContracts;
          
          modifier onlyAssetContracts() {
              require(_assetContracts[msg.sender], "You cannot call this function!");
              _;
          }
          
          function assetContracts(address input) public view returns (bool) {
              return _assetContracts[input];
          }
       
          function addAssetContracts(address input) public onlyPrimary{
               require(input != address(this));
               require(input != msg.sender);
               require(input != address(0));
               require(!assetContracts(input));
               
              _assetContracts[input] = true;
          }
          
          function removeAssetContracts(address input) public onlyPrimary{
               require(assetContracts(input));
              _assetContracts[input] = false;
          }
          
      }
      
      interface EthPricer{
          function ethUpper() external view returns (uint256);
          function ethLower() external view returns (uint256);
      }
      
      contract EthPriceable is assetContractable{
          
          address private _ethPricerAddress;
          
          function ethUpper() internal view returns (uint256) {
              return EthPricer(_ethPricerAddress).ethUpper();
          }
          
          function ethLower() internal view returns (uint256) {
              return EthPricer(_ethPricerAddress).ethLower();
          }
          
          function setEthPricerAddress(address input) public onlyPrimary {
              require(input != address(this));
              require(!assetContracts(input));
              require(input != msg.sender);
              require(input != address(0));
          
              _ethPricerAddress = input;
          }
          
          function ethPricerAddress() public view onlyAssetContracts returns (address) {
              return _ethPricerAddress;
          }
      
      }
      
      interface Assetcontract{
          function assetPricerAddress() external view returns (address payable);
          function AssetMint(address sender, uint256 valuesent) external;
          function isShort() external view returns (bool);
      }
      
      interface AssetPricer{
          function updateAssetPrice() external payable returns (bytes32);
          function Fee() external returns (uint256);
          function assetUpper(bool isShort) external view returns (uint256);
          function assetLower(bool isShort) external view returns (uint256);
          function updateGasPrice() external;
      }
      
      contract AssetPriceGettable is assetContractable{
          
          using SafeMath for uint256;
      
          uint256 internal _multiplier = 0;
          
          function multiplier() public view onlyAssetContracts returns (uint256) {
              return _multiplier;
          }
          
          function setMultiplier(uint256 input) public onlyPrimary {
              require(input <= 9999999900);
              _multiplier = input;
          }
          
          function aPA(address assetContractAddress) private view returns (address){
              return Assetcontract(assetContractAddress).assetPricerAddress();
          }
      
          function Fee(address aCA) internal returns (uint256) {
              AssetPricer(aPA(aCA)).updateGasPrice();
              uint fee = AssetPricer(aPA(aCA)).Fee();
              return (fee.mul(_multiplier.add(100))).div(100);
          }
          
          function assetUpper(address aCA) internal view returns (uint256) {
              bool isShort = Assetcontract(aCA).isShort();
              return AssetPricer(aPA(aCA)).assetUpper(isShort);
          }
          
          function assetLower(address aCA) internal view returns (uint256) {
              bool isShort = Assetcontract(aCA).isShort();
              return AssetPricer(aPA(aCA)).assetLower(isShort);
          }
      
          function updateAssetPrice(address aCA) internal returns (bytes32) {
              address payable sendto = address(uint160(aPA(aCA)));
              AssetPricer(sendto).updateGasPrice();
              return AssetPricer(sendto).updateAssetPrice.value(AssetPricer(sendto).Fee())();
          }
          
          function isAssetPricerAddress(address aCA, address input) internal view returns (bool) {
              return aPA(aCA) == input;
          }
      
      }
      
      contract ERC20 is IERC20, EthPriceable, AssetPriceGettable{
          using SafeMath for uint256;
          mapping (address => uint256) private _balances;
          mapping (address => mapping (address => uint256)) private _allowances;
          uint256 private _totalSupply;
          
          uint constant internal DECIMAL = 10**18;
          
          mapping(bytes32=>customer) internal Customers;
          mapping(uint=>uint) private withdrawPerBlock;
          
          enum IdType { gettingAsset, gettingUSD}
          
          struct customer { 
              address sender;
              uint256 valuesent;
              address Assetcontract;
              IdType mytype;
          }
          
          uint256 private withdrawThreshold = 1;
          
          function updateWithdrawThreshold(uint256 _withdrawThreshold) public onlyPrimary {
              withdrawThreshold = _withdrawThreshold;
          }
          
          //Max you can withdraw in USD per block
          function withdrawMAX() public view returns (uint256){
              
              uint usdMAX = (address(this).balance.mul(ethUpper())).div(withdrawThreshold.mul(DECIMAL));
            
              if(withdrawPerBlock[block.number] < usdMAX){
                  return usdMAX.sub(withdrawPerBlock[block.number]);
              }else{
                  return 0;
              }
          }
      
          function totalSupply() public view returns (uint256) {
              return _totalSupply;
          }
      
          function balanceOf(address account) public view returns (uint256) {
              return _balances[account];
          }
      
          function transfer(address recipient, uint256 amount) public returns (bool) {
              _transfer(msg.sender, recipient, amount);
              return true;
          }
      
          function allowance(address owner, address spender) public view returns (uint256) {
              return _allowances[owner][spender];
          }
      
          function approve(address spender, uint256 value) public returns (bool) {
              _approve(msg.sender, spender, value);
              return true;
          }
      
          function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
              _transfer(sender, recipient, amount);
              _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: transfer amount exceeds allowance"));
              return true;
          }
      
          function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
              _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue));
              return true;
          }
      
          function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
              _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
              return true;
          }
      
          function _transfer(address sender, address recipient, uint256 amount) internal {
              require(sender != address(0), "ERC20: transfer from the zero address");
              require(recipient != address(0), "ERC20: transfer to the zero address");
              
              if(recipient == address(this)){
                  require(amount <= withdrawMAX(), "Amount sent is too big");
                  withdrawPerBlock[block.number] = withdrawPerBlock[block.number].add(amount);
                  
                  _burn(sender,amount);
                  address payable sendto = address(uint160(sender));
                  sendto.transfer(amount.mul(DECIMAL).div(ethUpper()));
                  
              }else if(assetContracts(recipient)){
      
                 uint USDFee = (Fee(recipient).mul(ethUpper())).div(DECIMAL);
                 require(amount > USDFee, "Amount sent is too small");
                 
                 _burn(sender,amount);
                 bytes32 CustomerId = updateAssetPrice(recipient);
                 Customers[CustomerId] = customer(sender, amount.sub(USDFee), recipient, IdType.gettingAsset);
                  
              }else{
                  _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
                  _balances[recipient] = _balances[recipient].add(amount);
              }
              
              emit Transfer(sender, recipient, amount);
          }
      
          function _mint(address account, uint256 amount,address sender ) internal {
              require(account != address(0), "ERC20: mint to the zero address");
      
              _totalSupply = _totalSupply.add(amount);
              _balances[account] = _balances[account].add(amount);
              emit Transfer(sender, account, amount);
          }
      
          function _burn(address account, uint256 value) internal {
              require(account != address(0), "ERC20: burn from the zero address");
      
              _balances[account] = _balances[account].sub(value, "ERC20: burn amount exceeds balance");
              _totalSupply = _totalSupply.sub(value);
          }
          
          function _approve(address owner, address spender, uint256 value) internal {
              require(owner != address(0), "ERC20: approve from the zero address");
              require(spender != address(0), "ERC20: approve to the zero address");
      
              _allowances[owner][spender] = value;
              emit Approval(owner, spender, value);
          }
         
      }
      
      contract ERC20Detailed is IERC20 {
          string private _name;
          string private _symbol;
          uint8 private _decimals;
      
          constructor (string memory name, string memory symbol, uint8 decimals) public {
              _name = name;
              _symbol = symbol;
              _decimals = decimals;
          }
      
          function name() public view returns (string memory) {
              return _name;
          }
      
          function symbol() public view returns (string memory) {
              return _symbol;
          }
      
          function decimals() public view returns (uint8) {
              return _decimals;
          }
      }
      
      interface token {
          function balanceOf(address input) external returns (uint256);
          function transfer(address input, uint amount) external;
      }
      
      contract MainToken is ERC20, ERC20Detailed{
      
          constructor () public ERC20Detailed("Onyx USD", "OUSD", 18){
              _mint(primary(),10**18, address(this));
          }
          
          function () external payable {
              uint256 amount = (msg.value.mul(ethLower())).div(DECIMAL);
              _mint(msg.sender,amount,address(this));
          }
          
          function sendFunds() external payable {}
          
          function USDtrade(address sender, uint assetAmount) public onlyAssetContracts{
             bytes32 customerId = updateAssetPrice(msg.sender);
             Customers[customerId] = customer(sender, assetAmount, msg.sender,IdType.gettingUSD);
          }
          
          function assetPriceUpdated(bytes32 customerId, bool marketOpen) public {
             address sender    = Customers[customerId].sender;
             uint256 valuesent = Customers[customerId].valuesent;
             address AC        = Customers[customerId].Assetcontract;
             IdType mytype     = Customers[customerId].mytype;
             
             require(isAssetPricerAddress(AC, msg.sender));
             require(msg.sender != address(0));
             
             if(mytype == IdType.gettingUSD){
      
                  if(marketOpen){
                     uint amount = ((valuesent.mul(AssetPricer(msg.sender).assetLower(Assetcontract(AC).isShort())).mul(100)).sub(AssetPricer(msg.sender).Fee().mul(_multiplier+100).mul(ethUpper())))/(10**20);
                     _mint(sender, amount, AC);
                     
                  }else{
                     uint amount = valuesent.sub((AssetPricer(msg.sender).Fee().mul(_multiplier+100).mul(ethUpper())).div(AssetPricer(msg.sender).assetLower(Assetcontract(AC).isShort()).mul(100)));
                     Assetcontract(AC).AssetMint(sender,amount); 
                  }
      
              }else if(mytype == IdType.gettingAsset){
      
                  if(marketOpen){
                     uint amount = (valuesent.mul(DECIMAL)).div(assetUpper(AC));
                     Assetcontract(AC).AssetMint(sender,amount);
      
                  }else{
                      _mint(sender, valuesent, AC);
                  }
              }
          }
          
          function USDMint(address to, uint256 valuesent) public onlyPrimary{
              _mint(to,valuesent, address(this));
          }
       
          function USDBurn(address to, uint256 valuesent) public onlyPrimary {
              _burn(to,valuesent);
              emit Transfer(to, address(this), valuesent);
          }
          
          
          function getStuckTokens(address _tokenAddress) public {
              token(_tokenAddress).transfer(primary(), token(_tokenAddress).balanceOf(address(this)));
          }
         
          function withdrawEth(uint256 amount) public onlyPrimary{
              address payable sendto = address(uint160(primary()));
              sendto.transfer(amount);
          } 
      }

      File 2 of 3: Medianizer
      /// return median value of feeds
      
      // Copyright (C) 2017  DappHub, LLC
      
      // Licensed under the Apache License, Version 2.0 (the "License").
      // You may not use this file except in compliance with the License.
      
      // Unless required by applicable law or agreed to in writing, software
      // distributed under the License is distributed on an "AS IS" BASIS,
      // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND (express or implied).
      
      pragma solidity ^0.4.8;
      
      contract DSAuthority {
          function canCall(
              address src, address dst, bytes4 sig
          ) constant returns (bool);
      }
      
      contract DSAuthEvents {
          event LogSetAuthority (address indexed authority);
          event LogSetOwner     (address indexed owner);
      }
      
      contract DSAuth is DSAuthEvents {
          DSAuthority  public  authority;
          address      public  owner;
      
          function DSAuth() {
              owner = msg.sender;
              LogSetOwner(msg.sender);
          }
      
          function setOwner(address owner_)
              auth
          {
              owner = owner_;
              LogSetOwner(owner);
          }
      
          function setAuthority(DSAuthority authority_)
              auth
          {
              authority = authority_;
              LogSetAuthority(authority);
          }
      
          modifier auth {
              assert(isAuthorized(msg.sender, msg.sig));
              _;
          }
      
          modifier authorized(bytes4 sig) {
              assert(isAuthorized(msg.sender, sig));
              _;
          }
      
          function isAuthorized(address src, bytes4 sig) internal returns (bool) {
              if (src == address(this)) {
                  return true;
              } else if (src == owner) {
                  return true;
              } else if (authority == DSAuthority(0)) {
                  return false;
              } else {
                  return authority.canCall(src, this, sig);
              }
          }
      
          function assert(bool x) internal {
              if (!x) throw;
          }
      }
      
      contract DSNote {
          event LogNote(
              bytes4   indexed  sig,
              address  indexed  guy,
              bytes32  indexed  foo,
              bytes32  indexed  bar,
      	uint	 	  wad,
              bytes             fax
          ) anonymous;
      
          modifier note {
              bytes32 foo;
              bytes32 bar;
      
              assembly {
                  foo := calldataload(4)
                  bar := calldataload(36)
              }
      
              LogNote(msg.sig, msg.sender, foo, bar, msg.value, msg.data);
      
              _;
          }
      }
      
      contract DSMath {
          
          /*
          standard uint256 functions
           */
      
          function add(uint256 x, uint256 y) constant internal returns (uint256 z) {
              assert((z = x + y) >= x);
          }
      
          function sub(uint256 x, uint256 y) constant internal returns (uint256 z) {
              assert((z = x - y) <= x);
          }
      
          function mul(uint256 x, uint256 y) constant internal returns (uint256 z) {
              assert((z = x * y) >= x);
          }
      
          function div(uint256 x, uint256 y) constant internal returns (uint256 z) {
              z = x / y;
          }
      
          function min(uint256 x, uint256 y) constant internal returns (uint256 z) {
              return x <= y ? x : y;
          }
          function max(uint256 x, uint256 y) constant internal returns (uint256 z) {
              return x >= y ? x : y;
          }
      
          /*
          uint128 functions (h is for half)
           */
      
      
          function hadd(uint128 x, uint128 y) constant internal returns (uint128 z) {
              assert((z = x + y) >= x);
          }
      
          function hsub(uint128 x, uint128 y) constant internal returns (uint128 z) {
              assert((z = x - y) <= x);
          }
      
          function hmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
              assert((z = x * y) >= x);
          }
      
          function hdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
              z = x / y;
          }
      
          function hmin(uint128 x, uint128 y) constant internal returns (uint128 z) {
              return x <= y ? x : y;
          }
          function hmax(uint128 x, uint128 y) constant internal returns (uint128 z) {
              return x >= y ? x : y;
          }
      
      
          /*
          int256 functions
           */
      
          function imin(int256 x, int256 y) constant internal returns (int256 z) {
              return x <= y ? x : y;
          }
          function imax(int256 x, int256 y) constant internal returns (int256 z) {
              return x >= y ? x : y;
          }
      
          /*
          WAD math
           */
      
          uint128 constant WAD = 10 ** 18;
      
          function wadd(uint128 x, uint128 y) constant internal returns (uint128) {
              return hadd(x, y);
          }
      
          function wsub(uint128 x, uint128 y) constant internal returns (uint128) {
              return hsub(x, y);
          }
      
          function wmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
              z = cast((uint256(x) * y + WAD / 2) / WAD);
          }
      
          function wdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
              z = cast((uint256(x) * WAD + y / 2) / y);
          }
      
          function wmin(uint128 x, uint128 y) constant internal returns (uint128) {
              return hmin(x, y);
          }
          function wmax(uint128 x, uint128 y) constant internal returns (uint128) {
              return hmax(x, y);
          }
      
          /*
          RAY math
           */
      
          uint128 constant RAY = 10 ** 27;
      
          function radd(uint128 x, uint128 y) constant internal returns (uint128) {
              return hadd(x, y);
          }
      
          function rsub(uint128 x, uint128 y) constant internal returns (uint128) {
              return hsub(x, y);
          }
      
          function rmul(uint128 x, uint128 y) constant internal returns (uint128 z) {
              z = cast((uint256(x) * y + RAY / 2) / RAY);
          }
      
          function rdiv(uint128 x, uint128 y) constant internal returns (uint128 z) {
              z = cast((uint256(x) * RAY + y / 2) / y);
          }
      
          function rpow(uint128 x, uint64 n) constant internal returns (uint128 z) {
              // This famous algorithm is called "exponentiation by squaring"
              // and calculates x^n with x as fixed-point and n as regular unsigned.
              //
              // It's O(log n), instead of O(n) for naive repeated multiplication.
              //
              // These facts are why it works:
              //
              //  If n is even, then x^n = (x^2)^(n/2).
              //  If n is odd,  then x^n = x * x^(n-1),
              //   and applying the equation for even x gives
              //    x^n = x * (x^2)^((n-1) / 2).
              //
              //  Also, EVM division is flooring and
              //    floor[(n-1) / 2] = floor[n / 2].
      
              z = n % 2 != 0 ? x : RAY;
      
              for (n /= 2; n != 0; n /= 2) {
                  x = rmul(x, x);
      
                  if (n % 2 != 0) {
                      z = rmul(z, x);
                  }
              }
          }
      
          function rmin(uint128 x, uint128 y) constant internal returns (uint128) {
              return hmin(x, y);
          }
          function rmax(uint128 x, uint128 y) constant internal returns (uint128) {
              return hmax(x, y);
          }
      
          function cast(uint256 x) constant internal returns (uint128 z) {
              assert((z = uint128(x)) == x);
          }
      
      }
      
      contract DSThing is DSAuth, DSNote, DSMath {
      }
      
      contract DSValue is DSThing {
          bool    has;
          bytes32 val;
          function peek() constant returns (bytes32, bool) {
              return (val,has);
          }
          function read() constant returns (bytes32) {
              var (wut, has) = peek();
              assert(has);
              return wut;
          }
          function poke(bytes32 wut) note auth {
              val = wut;
              has = true;
          }
          function void() note auth { // unset the value
              has = false;
          }
      }
      
      contract Medianizer is DSValue {
          mapping (bytes12 => address) public values;
          mapping (address => bytes12) public indexes;
          bytes12 public next = 0x1;
      
          uint96 public min = 0x1;
      
          function set(address wat) auth {
              bytes12 nextId = bytes12(uint96(next) + 1);
              assert(nextId != 0x0);
              set(next, wat);
              next = nextId;
          }
      
          function set(bytes12 pos, address wat) note auth {
              if (pos == 0x0) throw;
      
              if (wat != 0 && indexes[wat] != 0) throw;
      
              indexes[values[pos]] = 0; // Making sure to remove a possible existing address in that position
      
              if (wat != 0) {
                  indexes[wat] = pos;
              }
      
              values[pos] = wat;
          }
      
          function setMin(uint96 min_) note auth {
              if (min_ == 0x0) throw;
              min = min_;
          }
      
          function setNext(bytes12 next_) note auth {
              if (next_ == 0x0) throw;
              next = next_;
          }
      
          function unset(bytes12 pos) {
              set(pos, 0);
          }
      
          function unset(address wat) {
              set(indexes[wat], 0);
          }
      
          function poke() {
              poke(0);
          }
      
          function poke(bytes32) note {
              (val, has) = compute();
          }
      
          function compute() constant returns (bytes32, bool) {
              bytes32[] memory wuts = new bytes32[](uint96(next) - 1);
              uint96 ctr = 0;
              for (uint96 i = 1; i < uint96(next); i++) {
                  if (values[bytes12(i)] != 0) {
                      var (wut, wuz) = DSValue(values[bytes12(i)]).peek();
                      if (wuz) {
                          if (ctr == 0 || wut >= wuts[ctr - 1]) {
                              wuts[ctr] = wut;
                          } else {
                              uint96 j = 0;
                              while (wut >= wuts[j]) {
                                  j++;
                              }
                              for (uint96 k = ctr; k > j; k--) {
                                  wuts[k] = wuts[k - 1];
                              }
                              wuts[j] = wut;
                          }
                          ctr++;
                      }
                  }
              }
      
              if (ctr < min) return (val, false);
      
              bytes32 value;
              if (ctr % 2 == 0) {
                  uint128 val1 = uint128(wuts[(ctr / 2) - 1]);
                  uint128 val2 = uint128(wuts[ctr / 2]);
                  value = bytes32(wdiv(hadd(val1, val2), 2 ether));
              } else {
                  value = wuts[(ctr - 1) / 2];
              }
      
              return (value, true);
          }
      
      }

      File 3 of 3: FiatContract
      pragma solidity 0.4.15;
      
      /*
      
          Crypto Market Prices via Ethereum Smart Contract
      
          A community driven smart contract that lets your contracts use fiat
          amounts in USD, EURO, and GBP. Need to charge $10.50 for a contract call?
          With this contract, you can convert ETH and other crypto's.
      
          Repo: https://github.com/hunterlong/fiatcontract
          Website: https://fiatcontract.com
      
          Examples:
      
            FiatContract price = FiatContract(CONTRACT_ADDRESS);
      
            uint256 ethCent = price.USD(0);        // returns $0.01 worth of ETH in USD.
            uint256 weiAmount = ethCent * 2500     // returns $25.00 worth of ETH in USD
            require(msg.value == weiAmount);       // require $25.00 worth of ETH as a payment
            
          Please look at Repo or Website to get Currency ID values.
      
          @author Hunter Long
      */
      
      contract FiatContract {
      
          mapping(uint => Token) public tokens;
      
          address public sender;
          address public creator;
      
          event NewPrice(uint id, string token);
          event DeletePrice(uint id);
          event UpdatedPrice(uint id);
          event RequestUpdate(uint id);
          event Donation(address from);
      
          struct Token {
              string name;
              uint256 eth;
              uint256 usd;
              uint256 eur;
              uint256 gbp;
              uint block;
          }
      
          // initialize function
          function FiatContract() {
              creator = msg.sender;
              sender = msg.sender;
          }
      
          // returns the Token struct
          function getToken(uint _id) internal constant returns (Token) {
              return tokens[_id];
          }
      
          // returns rate price of coin related to ETH.
          function ETH(uint _id) constant returns (uint256) {
              return tokens[_id].eth;
          }
      
          // returns 0.01 value in United States Dollar
          function USD(uint _id) constant returns (uint256) {
              return tokens[_id].usd;
          }
      
          // returns 0.01 value in Euro
          function EUR(uint _id) constant returns (uint256) {
              return tokens[_id].eur;
          }
      
          // returns 0.01 value in British Pound
          function GBP(uint _id) constant returns (uint256) {
              return tokens[_id].gbp;
          }
      
          // returns block when price was updated last
          function updatedAt(uint _id) constant returns (uint) {
              return tokens[_id].block;
          }
      
          // update market rates in USD, EURO, and GBP for a specific coin
          function update(uint id, string _token, uint256 eth, uint256 usd, uint256 eur, uint256 gbp) external {
              require(msg.sender==sender);
              tokens[id] = Token(_token, eth, usd, eur, gbp, block.number);
              NewPrice(id, _token);
          }
      
          // delete a token from the contract
          function deleteToken(uint id) {
              require(msg.sender==creator);
              DeletePrice(id);
              delete tokens[id];
          }
      
          // change creator address
          function changeCreator(address _creator){
              require(msg.sender==creator);
              creator = _creator;
          }
      
          // change sender address
          function changeSender(address _sender){
              require(msg.sender==creator);
              sender = _sender;
          }
      
          // execute function for creator if ERC20's get stuck in this wallet
          function execute(address _to, uint _value, bytes _data) external returns (bytes32 _r) {
              require(msg.sender==creator);
              require(_to.call.value(_value)(_data));
              return 0;
          }
      
          // default function so this contract can accept ETH with low gas limits.
          function() payable {
      
          }
      
          // public function for requesting an updated price from server
          // using this function requires a payment of $0.35 USD
          function requestUpdate(uint id) external payable {
              uint256 weiAmount = tokens[0].usd * 35;
              require(msg.value >= weiAmount);
              sender.transfer(msg.value);
              RequestUpdate(id);
          }
      
          // donation function that get forwarded to the contract updater
          function donate() external payable {
              require(msg.value >= 0);
              sender.transfer(msg.value);
              Donation(msg.sender);
          }
      
      }