Contract 0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e 7

 

Contract Overview

Balance:
0 MATIC

MATIC Value:
$0.00

Token:
 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x678440b6478cc68497666597af10d2b85b7bd3518a1974ddf7d4baf8fbf71b14Transfer From Wi...302508832022-07-02 12:05:452 hrs 4 mins ago0x1e00d69a0d3308c1207587497d530f99ec38dda5 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.00522277265 39.40733742
0x41912bb3ea8300804de7ca08d8a0961fa7513dfce18b8ba5c45d62eada926838Transfer From Wi...302506722022-07-02 11:58:272 hrs 11 mins ago0x1e00d69a0d3308c1207587497d530f99ec38dda5 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005317405886 35.533468449
0xd853982af3edafa1db4abefd1b58b1c6382c16b8da01b2096bbedc71b50e8ca3Transfer From Wi...302198412022-07-01 16:34:1521 hrs 35 mins ago0xb864250ff5ea1779e4aaf04097d1d5a20da6c107 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.00525034804 37.8193582
0xd16d46c1c2bf7c6065a3d38e7ecb12a89d2af585d5774e93179454bb9461afb0Transfer From Wi...302074972022-07-01 8:17:151 day 5 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.0074392109 57.606229728
0x1f36c8eacbee82a5fb6ab70dac91a63674ea9163872c599d6e348ea6ca85c484Transfer From Wi...302051722022-07-01 6:50:081 day 7 hrs ago0x21b17f93896819322a59cfc4772d5afc804f6fdd IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.006575859064 60.727892069
0xa2feaa27b656c0bbcd426a6da6b354f90db302c43de78f75af6a620f2a28c605Transfer From Wi...301692622022-06-30 8:51:312 days 5 hrs ago0x75e10f8fa325ed8a0f7cd92ab959427d2430675f IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.016151344518 104.964740752
0xfd662d1031eb6d4a0f9669effde3d797b62642d1eaf947bbb184182880f9b8bfTransfer From Wi...301626722022-06-30 4:52:012 days 9 hrs ago0x4fb08458199e80de9d8f39439d54e26d5f91e6db IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.006261728852 45.781572905
0x1f7f5b69d8b279f4f603460144d6b6405ebf3e849d5f00aeffec659d9bac3bc7Transfer From Wi...301528452022-06-29 22:48:342 days 15 hrs ago0x17e1ca830c68abfdd86870bfafc1dcc5afbdde61 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.007031864952 46.994078528
0xa76b26030e3511552fb6b4c8bc09446f85b7ec882de96a78d197dd1dcc9ae806Transfer From Wi...301421892022-06-29 16:03:312 days 22 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005496481846 42.559887927
0x4c8cdaee350abf00d2b6ae0b147c4834df859aebf7f5985cdd59d97acf86e287Transfer From Wi...301398902022-06-29 14:40:112 days 23 hrs ago0x51f262484f019e0cac2ecc32c82b7c37a01dd5a4 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.00876394997 58.560240885
0xfd89427cd2678c2b6644277973fe40931b8bd0fc56bce61a9c02860e68686612Transfer From Wi...301320622022-06-29 9:46:103 days 4 hrs ago0x4fb08458199e80de9d8f39439d54e26d5f91e6db IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.006308363855 46.13029415
0xfa70ce9ca90118f6ae2cfc256a1952ca66cba7e5d6d3cf7a0fde46e6a1e6d401Transfer From Wi...301225242022-06-29 3:54:423 days 10 hrs ago0x4919f5da960edaf34b36473c05a543d4c18bfc15 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.007447903681 41.811384212
0x4140b9ec1b263a381ec5bfdd41496fdf8bc78a7e316583df9c1844db48e6146aTransfer From Wi...301008312022-06-28 14:39:213 days 23 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.008302630614 64.298176325
0x89d32ade32a6c5de9694920f889b454d43e81adc8037c851128a90d3649d6e45Transfer From Wi...300924642022-06-28 9:27:234 days 4 hrs ago0x21b17f93896819322a59cfc4772d5afc804f6fdd IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.004714951577 43.54245851
0xaaac6e95db99a55d423d0380d2c63c656deb4c34b871bf7fd3dde4a8b1de2341Transfer From Wi...300923312022-06-28 9:22:094 days 4 hrs ago0x21b17f93896819322a59cfc4772d5afc804f6fdd IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005491703432 43.801871433
0xd57d4d6c45bde8530546ff52a4881565be2a9ba9c120e0883142a80c8d516ac8Transfer From Wi...300904672022-06-28 8:11:014 days 5 hrs ago0x4fb08458199e80de9d8f39439d54e26d5f91e6db IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.007840693703 57.325907727
0xca47cde088dcf0552719546ac05a1b63e5cff670afe6b618df8aad2cedbaa75dTransfer From Wi...300862802022-06-28 5:33:524 days 8 hrs ago0x75e10f8fa325ed8a0f7cd92ab959427d2430675f IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.007770687883 60.156748906
0x98fed02eeb923e29fc4d32d56c484433a9d9adda0f1a997e4913698ee673ff6bTransfer From Wi...300666862022-06-27 17:17:304 days 20 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.008830709743 87.727220504
0xda7e3a68ab8d600ca7e7f845da36c3248e21e222f77d6ee6a73200386acaddf5Transfer From Wi...300611782022-06-27 13:44:125 days 25 mins ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.03223162789 249.633104266
0xe632a1657cf1819ba2f4016d6a223fc7a026f9037e44854f5fecad0251f103a9Transfer From Wi...300570842022-06-27 11:11:365 days 2 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.004455661763 44.264032379
0x9671b3d162c27bad44bf2bf290242156e38a0ae7c437ce693295951b4cb4b60eTransfer From Wi...300560702022-06-27 10:34:305 days 3 hrs ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.004940926232 38.260527279
0x017cd3562cd82f2db661cd0a209a02b3e687b489cf2b48e0c39a287f7b7e12afTransfer From Wi...299086802022-06-23 14:00:169 days 9 mins ago0x21b17f93896819322a59cfc4772d5afc804f6fdd IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005405265382 50.54909598
0xa4ca70bc809a0889990198a4d53bfb76fd46a46dcf359a2ab8afadb8425556ecTransfer From Wi...299078712022-06-23 13:30:159 days 39 mins ago0x8d35bd9cab090af815d872e75d02d77ce826e481 IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.004910596358 38.032438722
0x7f7b09a71bbfdeb1cc4856a10a215cf30e096c72e27b07d47af56fc832022d56Transfer From Wi...298628472022-06-22 9:40:3310 days 4 hrs ago0x21b17f93896819322a59cfc4772d5afc804f6fdd IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005515284975 42.709451161
0x9b83d06a808ec8e73b28fb56af1dd8a1c79cbdcdc4c5f908d64de344755fcf2aTransfer From Wi...298622742022-06-22 9:18:4610 days 4 hrs ago0x8f81b7312f611e9155e2db0335ba53aa71a897ed IN  0xf0f49873c50765239f6f9534ba13c4fe16ed5f2e0 MATIC0.005288953653 45.386666672
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
Erc20ConversionProxy

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
File 1 of 7 : Erc20ConversionProxy.sol
pragma solidity ^0.5.0;

import "./ChainlinkConversionPath.sol";
import "./interfaces/ERC20FeeProxy.sol";


/**
 * @title Erc20ConversionProxy
 * @notice This contract convert from chainlink then swaps ERC20 tokens before paying a request thanks to a conversion payment proxy
  */
contract Erc20ConversionProxy {
  using SafeMath for uint256;

  address public paymentProxy;
  ChainlinkConversionPath public chainlinkConversionPath;

  constructor(address _paymentProxyAddress, address _chainlinkConversionPathAddress) public {
    paymentProxy = _paymentProxyAddress;
    chainlinkConversionPath = ChainlinkConversionPath(_chainlinkConversionPathAddress);
  }

  // Event to declare a conversion with a reference
  event TransferWithConversionAndReference(
    uint256 amount,
    address currency,
    bytes indexed paymentReference,
    uint256 feeAmount,
    uint256 maxRateTimespan
  );
  
  // Event to declare a transfer with a reference
  event TransferWithReferenceAndFee(
    address tokenAddress,
    address to,
    uint256 amount,
    bytes indexed paymentReference,
    uint256 feeAmount,
    address feeAddress
  );

  /**
   * @notice Performs an ERC20 token transfer with a reference computing the payment amount based on the request amount
   * @param _to Transfer recipient of the payement
   * @param _requestAmount Request amount
   * @param _path Conversion path
   * @param _paymentReference Reference of the payment related
   * @param _feeAmount The amount of the payment fee
   * @param _feeAddress The fee recipient
   * @param _maxToSpend Amount max that we can spend on the behalf of the user
   * @param _maxRateTimespan Max time span with the oldestrate, ignored if zero
   */
  function transferFromWithReferenceAndFee(
    address _to,
    uint256 _requestAmount,
    address[] calldata _path,
    bytes calldata _paymentReference,
    uint256 _feeAmount,
    address _feeAddress,
    uint256 _maxToSpend,
    uint256 _maxRateTimespan
  )
  external
  {
    (uint256 amountToPay, uint256 amountToPayInFees) = getConversions(
      _path,
      _requestAmount,
      _feeAmount,
      _maxRateTimespan);

    require(
      amountToPay.add(amountToPayInFees) <= _maxToSpend,
      "Amount to pay is over the user limit"
    );

    // Pay the request and fees
    (bool status, ) = paymentProxy.delegatecall(
      abi.encodeWithSignature(
        "transferFromWithReferenceAndFee(address,address,uint256,bytes,uint256,address)",
        // payment currency
        _path[_path.length - 1],
        _to,
        amountToPay,
        _paymentReference,
        amountToPayInFees,
        _feeAddress
      )
    );
    require(status, "transferFromWithReferenceAndFee failed");

    // Event to declare a transfer with a reference
    emit TransferWithConversionAndReference(
      _requestAmount,
      // request currency
      _path[0],
      _paymentReference,
      _feeAmount,
      _maxRateTimespan
    );
  }

  function getConversions(
    address[] memory _path,
    uint256 _requestAmount,
    uint256 _feeAmount,
    uint256 _maxRateTimespan
  )
    internal
    returns (uint256 amountToPay, uint256 amountToPayInFees)
  {
    (uint256 rate, uint256 oldestTimestampRate, uint256 decimals) = chainlinkConversionPath.getRate(_path);

    // Check rate timespan
    require(
      _maxRateTimespan == 0 || block.timestamp.sub(oldestTimestampRate) <= _maxRateTimespan,
      "aggregator rate is outdated"
    );

    // Get the amount to pay in the crypto currency chosen
    amountToPay = _requestAmount.mul(rate).div(decimals);
    amountToPayInFees = _feeAmount.mul(rate).div(decimals);
  }
}

File 2 of 7 : ChainlinkConversionPath.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.4.25 <0.7.0;

import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/roles/WhitelistAdminRole.sol";

interface ERC20fraction {
  function decimals() external view returns (uint8);
}

interface AggregatorFraction {
  function decimals() external view returns (uint8);
  function latestAnswer() external view returns (int256);
  function latestTimestamp() external view returns (uint256);
}


/**
 * @title ChainlinkConversionPath
 *
 * @notice ChainlinkConversionPath is a contract computing currency conversion rates based on Chainlink aggretators
 */
contract ChainlinkConversionPath is WhitelistAdminRole {
  using SafeMath for uint256;

  uint constant DECIMALS = 1e18;

  // Mapping of Chainlink aggregators (input currency => output currency => contract address)
  // input & output currencies are the addresses of the ERC20 contracts OR the sha3("currency code")
  mapping(address => mapping(address => address)) public allAggregators;

  // declare a new aggregator
  event AggregatorUpdated(address _input, address _output, address _aggregator);

  /**
    * @notice Update an aggregator
    * @param _input address representing the input currency
    * @param _output address representing the output currency
    * @param _aggregator address of the aggregator contract
  */
  function updateAggregator(address _input, address _output, address _aggregator)
    external
    onlyWhitelistAdmin
  {
    allAggregators[_input][_output] = _aggregator;
    emit AggregatorUpdated(_input, _output, _aggregator);
  }

  /**
    * @notice Update a list of aggregators
    * @param _inputs list of addresses representing the input currencies
    * @param _outputs list of addresses representing the output currencies
    * @param _aggregators list of addresses of the aggregator contracts
  */
  function updateAggregatorsList(address[] calldata _inputs, address[] calldata _outputs, address[] calldata _aggregators)
    external
    onlyWhitelistAdmin
  {
    require(_inputs.length == _outputs.length, "arrays must have the same length");
    require(_inputs.length == _aggregators.length, "arrays must have the same length");

    // For every conversions of the path
    for (uint i; i < _inputs.length; i++) {
      allAggregators[_inputs[i]][_outputs[i]] = _aggregators[i];
      emit AggregatorUpdated(_inputs[i], _outputs[i], _aggregators[i]);
    }
  }

  /**
  * @notice Computes the conversion of an amount through a list of intermediate conversions
  * @param _amountIn Amount to convert
  * @param _path List of addresses representing the currencies for the intermediate conversions
  * @return result The result after all the conversions
  * @return oldestRateTimestamp The oldest timestamp of the path
  */
  function getConversion(
    uint256 _amountIn,
    address[] calldata _path
  )
    external
    view
    returns (uint256 result, uint256 oldestRateTimestamp)
  {
    (uint256 rate, uint256 timestamp, uint256 decimals) = getRate(_path);

    // initialize the result
    result = _amountIn.mul(rate).div(decimals);

    oldestRateTimestamp = timestamp;
  }

  /**
  * @notice Computes the conversion rate from a list of currencies
  * @param _path List of addresses representing the currencies for the conversions
  * @return rate The rate
  * @return oldestRateTimestamp The oldest timestamp of the path
  * @return decimals of the conversion rate
  */
  function getRate(
    address[] memory _path
  )
    public
    view
    returns (uint256 rate, uint256 oldestRateTimestamp, uint256 decimals)
  {
    // initialize the result with 18 decimals (for more precision)
    rate = DECIMALS;
    decimals = DECIMALS;
    oldestRateTimestamp = block.timestamp;

    // For every conversion of the path
    for (uint i; i < _path.length - 1; i++) {
      (AggregatorFraction aggregator, bool reverseAggregator, uint256 decimalsInput, uint256 decimalsOutput) = getAggregatorAndDecimals(_path[i], _path[i + 1]);

      // store the latest timestamp of the path
      uint256 currentTimestamp = aggregator.latestTimestamp();
      if (currentTimestamp < oldestRateTimestamp) {
        oldestRateTimestamp = currentTimestamp;
      }

      // get the rate of the current step
      uint256 currentRate = uint256(aggregator.latestAnswer());
      // get the number of decimals of the current rate
      uint256 decimalsAggregator = uint256(aggregator.decimals());

      // mul with the difference of decimals before the current rate computation (for more precision)
      if (decimalsAggregator > decimalsInput) {
        rate = rate.mul(10**(decimalsAggregator-decimalsInput));
      }
      if (decimalsAggregator < decimalsOutput) {
        rate = rate.mul(10**(decimalsOutput-decimalsAggregator));
      }

      // Apply the current rate (if path uses an aggregator in the reverse way, div instead of mul)
      if (reverseAggregator) {
        rate = rate.mul(10**decimalsAggregator).div(currentRate);
      } else {
        rate = rate.mul(currentRate).div(10**decimalsAggregator);
      }

      // div with the difference of decimals AFTER the current rate computation (for more precision)
      if (decimalsAggregator < decimalsInput) {
        rate = rate.div(10**(decimalsInput-decimalsAggregator));
      }
      if (decimalsAggregator > decimalsOutput) {
        rate = rate.div(10**(decimalsAggregator-decimalsOutput));
      }
    }
  }

  /**
  * @notice Gets aggregators and decimals of two currencies
  * @param _input input Address
  * @param _output output Address
  * @return aggregator to get the rate between the two currencies
  * @return reverseAggregator true if the aggregator returned give the rate from _output to _input
  * @return decimalsInput decimals of _input
  * @return decimalsOutput decimals of _output
  */
  function getAggregatorAndDecimals(address _input, address _output)
    private
    view
    returns (AggregatorFraction aggregator, bool reverseAggregator, uint256 decimalsInput, uint256 decimalsOutput)
  {
    // Try to get the right aggregator for the conversion
    aggregator = AggregatorFraction(allAggregators[_input][_output]);
    reverseAggregator = false;

    // if no aggregator found we try to find an aggregator in the reverse way
    if (address(aggregator) == address(0x00)) {
      aggregator = AggregatorFraction(allAggregators[_output][_input]);
      reverseAggregator = true;
    }

    require(address(aggregator) != address(0x00), "No aggregator found");

    // get the decimals for the two currencies
    decimalsInput = getDecimals(_input);
    decimalsOutput = getDecimals(_output);
  }

  /**
  * @notice Gets decimals from an address currency
  * @param _addr address to check
  * @return number of decimals
  */
  function getDecimals(address _addr)
    private
    view
    returns (uint256 decimals)
  {
    // by default we assume it is FIAT so 8 decimals
    decimals = 8;
    // if address is the hash of the ETH currency
    if (_addr == address(0xF5AF88e117747e87fC5929F2ff87221B1447652E)) {
      decimals = 18;
    } else if (isContract(_addr)) {
      // otherwise, we get the decimals from the erc20 directly
      decimals = ERC20fraction(_addr).decimals();
    }
  }

  /**
  * @notice Checks if an address is a contract
  * @param _addr Address to check
  * @return true if the address hosts a contract, false otherwise
  */
  function isContract(address _addr)
    private
    view
    returns (bool)
  {
    uint32 size;
    // solium-disable security/no-inline-assembly
    assembly {
      size := extcodesize(_addr)
    }
    return (size > 0);
  }
}

File 3 of 7 : ERC20FeeProxy.sol
pragma solidity ^0.5.12;

interface IERC20FeeProxy {
  event TransferWithReferenceAndFee(
    address tokenAddress,
    address to,
    uint256 amount,
    bytes indexed paymentReference,
    uint256 feeAmount,
    address feeAddress
  );

  function transferFromWithReferenceAndFee(
    address _tokenAddress,
    address _to,
    uint256 _amount,
    bytes calldata _paymentReference,
    uint256 _feeAmount,
    address _feeAddress
    ) external;
}

File 4 of 7 : SafeMath.sol
pragma solidity ^0.5.0;

/**
 * @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.
     *
     * _Available since v2.4.0._
     */
    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: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/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.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        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.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

File 5 of 7 : WhitelistAdminRole.sol
pragma solidity ^0.5.0;

import "../../GSN/Context.sol";
import "../Roles.sol";

/**
 * @title WhitelistAdminRole
 * @dev WhitelistAdmins are responsible for assigning and removing Whitelisted accounts.
 */
contract WhitelistAdminRole is Context {
    using Roles for Roles.Role;

    event WhitelistAdminAdded(address indexed account);
    event WhitelistAdminRemoved(address indexed account);

    Roles.Role private _whitelistAdmins;

    constructor () internal {
        _addWhitelistAdmin(_msgSender());
    }

    modifier onlyWhitelistAdmin() {
        require(isWhitelistAdmin(_msgSender()), "WhitelistAdminRole: caller does not have the WhitelistAdmin role");
        _;
    }

    function isWhitelistAdmin(address account) public view returns (bool) {
        return _whitelistAdmins.has(account);
    }

    function addWhitelistAdmin(address account) public onlyWhitelistAdmin {
        _addWhitelistAdmin(account);
    }

    function renounceWhitelistAdmin() public {
        _removeWhitelistAdmin(_msgSender());
    }

    function _addWhitelistAdmin(address account) internal {
        _whitelistAdmins.add(account);
        emit WhitelistAdminAdded(account);
    }

    function _removeWhitelistAdmin(address account) internal {
        _whitelistAdmins.remove(account);
        emit WhitelistAdminRemoved(account);
    }
}

File 6 of 7 : Context.sol
pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with 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 { }
    // solhint-disable-previous-line no-empty-blocks

    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 https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 7 of 7 : Roles.sol
pragma solidity ^0.5.0;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_paymentProxyAddress","type":"address"},{"internalType":"address","name":"_chainlinkConversionPathAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"currency","type":"address"},{"indexed":true,"internalType":"bytes","name":"paymentReference","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxRateTimespan","type":"uint256"}],"name":"TransferWithConversionAndReference","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"bytes","name":"paymentReference","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"feeAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"feeAddress","type":"address"}],"name":"TransferWithReferenceAndFee","type":"event"},{"constant":true,"inputs":[],"name":"chainlinkConversionPath","outputs":[{"internalType":"contract ChainlinkConversionPath","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paymentProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_requestAmount","type":"uint256"},{"internalType":"address[]","name":"_path","type":"address[]"},{"internalType":"bytes","name":"_paymentReference","type":"bytes"},{"internalType":"uint256","name":"_feeAmount","type":"uint256"},{"internalType":"address","name":"_feeAddress","type":"address"},{"internalType":"uint256","name":"_maxToSpend","type":"uint256"},{"internalType":"uint256","name":"_maxRateTimespan","type":"uint256"}],"name":"transferFromWithReferenceAndFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50604051610d53380380610d538339818101604052604081101561003357600080fd5b810190808051906020019092919080519060200190929190505050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050610c73806100e06000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80633af2c012146100465780633cd3efef1461017d578063946647f1146101c7575b600080fd5b61017b600480360361010081101561005d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a457600080fd5b8201836020820111156100b657600080fd5b803590602001918460208302840111640100000000831117156100d857600080fd5b9091929391929390803590602001906401000000008111156100f957600080fd5b82018360208201111561010b57600080fd5b8035906020019184600183028401116401000000008311171561012d57600080fd5b909192939192939080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050610211565b005b610185610662565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6101cf610687565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000806102618a8a80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050508c88866106ad565b915091508361027982846108ab90919063ffffffff16565b11156102d0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180610c1b6024913960400191505060405180910390fd5b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b8b60018e8e90500381811061031c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff168e858c8c878c604051602401808873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001868152602001806020018481526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281038252868682818152602001925080828437600081840152601f19601f820116905080830192505050985050505050505050506040516020818303038152906040527fc219a14d000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106104d157805182526020820191506020810190506020830392506104ae565b6001836020036101000a038019825116818451168082178552505050505050905001915050600060405180830381855af49150503d8060008114610531576040519150601f19603f3d011682016040523d82523d6000602084013e610536565b606091505b5050905080610590576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180610bd46026913960400191505060405180910390fd5b888860405180838380828437808301925050509250505060405180910390207f96d0d1d75923f40b50f6fe74613b2c23239149607848fbca3941fee7ac041cdc8d8d8d60008181106105de57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff168a88604051808581526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200182815260200194505050505060405180910390a250505050505050505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000806000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166397edd4fa8a6040518263ffffffff1660e01b81526004018080602001828103825283818151815260200191508051906020019060200280838360005b8381101561074657808201518184015260208101905061072b565b505050509050019250505060606040518083038186803b15801561076957600080fd5b505afa15801561077d573d6000803e3d6000fd5b505050506040513d606081101561079357600080fd5b8101908080519060200190929190805190602001909291908051906020019092919050505092509250925060008614806107df5750856107dc834261093390919063ffffffff16565b11155b610851576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f61676772656761746f722072617465206973206f75746461746564000000000081525060200191505060405180910390fd5b61087681610868858b61097d90919063ffffffff16565b610a0390919063ffffffff16565b945061089d8161088f858a61097d90919063ffffffff16565b610a0390919063ffffffff16565b935050505094509492505050565b600080828401905083811015610929576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600061097583836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610a4d565b905092915050565b60008083141561099057600090506109fd565b60008284029050828482816109a157fe5b04146109f8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180610bfa6021913960400191505060405180910390fd5b809150505b92915050565b6000610a4583836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610b0d565b905092915050565b6000838311158290610afa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610abf578082015181840152602081019050610aa4565b50505050905090810190601f168015610aec5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b60008083118290610bb9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610b7e578082015181840152602081019050610b63565b50505050905090810190601f168015610bab5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581610bc557fe5b04905080915050939250505056fe7472616e7366657246726f6d576974685265666572656e6365416e64466565206661696c6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77416d6f756e7420746f20706179206973206f766572207468652075736572206c696d6974a265627a7a72315820a22437cd99e408aefbaff016114701134a4577bd4bdc05b28c7d372454ae846864736f6c634300051100320000000000000000000000000dfbee143b42b41efc5a6f87bfd1ffc78c2f0ac9000000000000000000000000eec4790306c43dc00cebbe4d0c36fadf8634b533

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000dfbee143b42b41efc5a6f87bfd1ffc78c2f0ac9000000000000000000000000eec4790306c43dc00cebbe4d0c36fadf8634b533

-----Decoded View---------------
Arg [0] : _paymentProxyAddress (address): 0x0dfbee143b42b41efc5a6f87bfd1ffc78c2f0ac9
Arg [1] : _chainlinkConversionPathAddress (address): 0xeec4790306c43dc00cebbe4d0c36fadf8634b533

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000dfbee143b42b41efc5a6f87bfd1ffc78c2f0ac9
Arg [1] : 000000000000000000000000eec4790306c43dc00cebbe4d0c36fadf8634b533


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.