ETH Price: $1,896.90 (-1.83%)
 
Transaction Hash
Method
Block
From
To
Deposit220423552025-03-14 3:12:593 days ago1741921979IN
0xEfE459dB...47638c983
0 ETH0.000098940.61346246
Deposit220311952025-03-12 13:50:234 days ago1741787423IN
0xEfE459dB...47638c983
0 ETH0.000240431.5637489
Deposit220131952025-03-10 1:29:357 days ago1741570175IN
0xEfE459dB...47638c983
0 ETH0.000238011.59775534
Deposit220124102025-03-09 22:51:237 days ago1741560683IN
0xEfE459dB...47638c983
0 ETH0.00020441.41761234
Deposit219921692025-03-07 2:57:4710 days ago1741316267IN
0xEfE459dB...47638c983
0 ETH0.000109380.75862256
Deposit219921652025-03-07 2:56:5910 days ago1741316219IN
0xEfE459dB...47638c983
0 ETH0.000131620.79267937
Claim219756962025-03-04 19:44:1112 days ago1741117451IN
0xEfE459dB...47638c983
0 ETH0.000361533.9675725
Claim219754812025-03-04 19:00:5912 days ago1741114859IN
0xEfE459dB...47638c983
0 ETH0.000237472.60608987
Claim219681342025-03-03 18:25:1113 days ago1741026311IN
0xEfE459dB...47638c983
0 ETH0.000432584.74730123
Withdraw219681282025-03-03 18:23:5913 days ago1741026239IN
0xEfE459dB...47638c983
0 ETH0.000618314.60260247
Deposit219653962025-03-03 9:14:3513 days ago1740993275IN
0xEfE459dB...47638c983
0 ETH0.000120050.80578493
Deposit219652742025-03-03 8:50:1113 days ago1740991811IN
0xEfE459dB...47638c983
0 ETH0.000147620.86397639
Deposit219164732025-02-24 13:26:4720 days ago1740403607IN
0xEfE459dB...47638c983
0 ETH0.000209571.29935208
Deposit219072502025-02-23 6:31:1121 days ago1740292271IN
0xEfE459dB...47638c983
0 ETH0.000164391.14014404
Deposit219042762025-02-22 20:31:5922 days ago1740256319IN
0xEfE459dB...47638c983
0 ETH0.000210891.3075624
Deposit219002552025-02-22 7:02:3522 days ago1740207755IN
0xEfE459dB...47638c983
0 ETH0.000104030.64498662
Deposit219001312025-02-22 6:37:3522 days ago1740206255IN
0xEfE459dB...47638c983
0 ETH0.000164111.13814139
Claim218959792025-02-21 16:42:3523 days ago1740156155IN
0xEfE459dB...47638c983
0 ETH0.003357689.13958938
Deposit218950552025-02-21 13:36:4723 days ago1740145007IN
0xEfE459dB...47638c983
0.01115013 ETH0.000237151.8380356
Deposit218826492025-02-19 19:57:3525 days ago1739995055IN
0xEfE459dB...47638c983
0 ETH0.000045431.26320568
Deposit218826482025-02-19 19:57:2325 days ago1739995043IN
0xEfE459dB...47638c983
0 ETH0.000184281.23714456
Deposit218820432025-02-19 17:55:3525 days ago1739987735IN
0xEfE459dB...47638c983
0 ETH0.000306682.05876419
Deposit218767832025-02-19 0:16:5926 days ago1739924219IN
0xEfE459dB...47638c983
0 ETH0.00019341.19912951
Deposit218752612025-02-18 19:10:4726 days ago1739905847IN
0xEfE459dB...47638c983
0 ETH0.000254471.70828155
Deposit218742502025-02-18 15:47:3526 days ago1739893655IN
0xEfE459dB...47638c983
0 ETH0.00044772.6959006
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer219756962025-03-04 19:44:1112 days ago1741117451
0xEfE459dB...47638c983
0.000099 ETH
Transfer219756962025-03-04 19:44:1112 days ago1741117451
0xEfE459dB...47638c983
0.00336679 ETH
Transfer219754812025-03-04 19:00:5912 days ago1741114859
0xEfE459dB...47638c983
0.01103863 ETH
Transfer219754812025-03-04 19:00:5912 days ago1741114859
0xEfE459dB...47638c983
0.00556859 ETH
Transfer219681342025-03-03 18:25:1113 days ago1741026311
0xEfE459dB...47638c983
0.0000099 ETH
Transfer219681342025-03-03 18:25:1113 days ago1741026311
0xEfE459dB...47638c983
0.00106461 ETH
Add Rewards219681282025-03-03 18:23:5913 days ago1741026239
0xEfE459dB...47638c983
0.0001126 ETH
Transfer202581152024-07-08 0:08:23252 days ago1720397303
0xEfE459dB...47638c983
0.4455 ETH
Transfer198171062024-05-07 8:50:35313 days ago1715071835
0xEfE459dB...47638c983
0.12474 ETH
Transfer198132542024-05-06 19:53:47314 days ago1715025227
0xEfE459dB...47638c983
0.891 ETH
Transfer198120502024-05-06 15:51:47314 days ago1715010707
0xEfE459dB...47638c983
0.04455 ETH
Transfer198119902024-05-06 15:39:47314 days ago1715009987
0xEfE459dB...47638c983
0.1782 ETH
Transfer198116992024-05-06 14:40:47314 days ago1715006447
0xEfE459dB...47638c983
0.891 ETH
Transfer198113612024-05-06 13:32:23314 days ago1715002343
0xEfE459dB...47638c983
0.891 ETH
Transfer198111262024-05-06 12:45:11314 days ago1714999511
0xEfE459dB...47638c983
0.1782 ETH
Transfer198110242024-05-06 12:24:35314 days ago1714998275
0xEfE459dB...47638c983
0.891 ETH
Transfer198110042024-05-06 12:20:35314 days ago1714998035
0xEfE459dB...47638c983
0.001782 ETH
Transfer198109942024-05-06 12:18:35314 days ago1714997915
0xEfE459dB...47638c983
0.9801 ETH
Transfer198109672024-05-06 12:12:59314 days ago1714997579
0xEfE459dB...47638c983
1.0692 ETH
Transfer198109472024-05-06 12:08:59314 days ago1714997339
0xEfE459dB...47638c983
0.150579 ETH
Transfer198109432024-05-06 12:08:11314 days ago1714997291
0xEfE459dB...47638c983
1.782 ETH
Transfer198109382024-05-06 12:07:11314 days ago1714997231
0xEfE459dB...47638c983
0.891 ETH
Transfer198109292024-05-06 12:05:23314 days ago1714997123
0xEfE459dB...47638c983
0.1610037 ETH
Transfer198109252024-05-06 12:04:35314 days ago1714997075
0xEfE459dB...47638c983
0.455301 ETH
Transfer198109242024-05-06 12:04:23314 days ago1714997063
0xEfE459dB...47638c983
0.40095 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RiceFields

Compiler Version
v0.8.25+commit.b61c2a91

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 11 : RiceFields.sol
// contracts/RiceFields.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IRewardFarmers.sol";
import "./libraries/ERC20Helpers.sol";
import "./interfaces/IFARM.sol";



/**
 *  
 *   .d8888b.  d8b                        888           .d8888b.                  d8b                                       
 *  d88P  Y88b Y8P                        888          d88P  Y88b                 Y8P                                       
 *  Y88b.                                 888          888    888                                                           
 *   "Y888b.   888 88888b.d88b.  88888b.  888  .d88b.  888        888d888 8888b.  888 88888b.       .d88b.  888d888 .d88b.  
 *      "Y88b. 888 888 "888 "88b 888 "88b 888 d8P  Y8b 888  88888 888P"      "88b 888 888 "88b     d88""88b 888P"  d88P"88b 
 *        "888 888 888  888  888 888  888 888 88888888 888    888 888    .d888888 888 888  888     888  888 888    888  888 
 *  Y88b  d88P 888 888  888  888 888 d88P 888 Y8b.     Y88b  d88P 888    888  888 888 888  888 d8b Y88..88P 888    Y88b 888 
 *   "Y8888P"  888 888  888  888 88888P"  888  "Y8888   "Y8888P88 888    "Y888888 888 888  888 Y8P  "Y88P"  888     "Y88888 
 *                               888                                                                                    888 
 *                               888                                                                               Y8b d88P 
 *                               888                                                                                "Y88P"  
 */



/**
 * @title RiceFields contract
 * @dev
 */
contract RiceFields is ReentrancyGuard, Ownable {
  uint256 public PRECISION = 10**18;

  IRewardFarmers rewardFarmers;

  struct TokenInfo {
    address contractAddress;
    uint256 decimals;
    string symbol;
    string name;
  }

  struct DistributionInfo {
    Distribution distribution;
    uint256 uncommonRewardId;
    uint256 currentTimestamp;
    bool hasUncommonReward;
    uint256 userAllocated;
    uint256 tokenOutPrice;
    uint256 tokenInPrice;
    uint256 userDeposits;
    bool userHasClaimed;
    TokenInfo tokenOUT;
    TokenInfo tokenIN;
    uint256 rewardId;
  }

  mapping(uint256 => mapping(address => Deposit)) public deposits;
  struct Distribution {
    uint256 totalTokensPerDeposit;
    uint256 uncommonRewardId;
    uint256 percentReturned; // divided by 10_000
    uint256 tokensPerSecond;
    bool hasUncommonReward;
    uint256 totalDeposited;
    bool rewardDistributed;
    uint256 lastDepositAt;
    bool ownerWithdrawn;
    uint256 platformFee;
    uint256 startTime;
    uint256 amountOUT;
    uint256 duration;
    uint256 endTime;
    string ipfsHash;
    address creator;
    uint256 id;

    string description;
    string name;

    uint256 nextActiveId;
    uint256 prevActiveId;

    IERC20Metadata tokenIN;
    IERC20Metadata tokenOUT;
  }

  uint256 public newestActiveDistributionId;

  struct Deposit {
    uint256 previouslyAllocated;
    uint256 amount;
    bool claimed;
  }

  Distribution[] public distributions;

  mapping(address => uint256[]) public userDistributions; // To track distributions a user has deposited into or created

  event DistributionCreated(
    uint256 id, address creator, string name, string description,
    uint256 duration, string ipfsHash, uint256 amountOUT,
    uint256 percentReturned, address tokenOUT, address tokenIN
  );
  event Deposited(uint256 distributionId, address indexed user, uint256 amount);
  event Claim(uint256 distributionId, address indexed user, uint256 amount, uint256 ethAmount);

  uint256 public platformFee = 100; // divided by 10_000

  /**
  * @dev Constructor to initialize the contract with the RewardFarmers contract.
  * @param _farm Address of the RewardFarmers contract.
  */
  constructor(IRewardFarmers _farm) {
    rewardFarmers = _farm;
  }

  /**
  * @dev Returns the number of distributions created.
  * @return The total count of distributions.
  */
  function distributionCount() public view returns (uint256) {
    return distributions.length;
  }

  /**
  * @dev Sets the farmer fee percentage. Can only be called by the contract owner.
  * @notice This function allows the contract owner to update the farmer fee percentage.
  * The fee is a percentage of the total deposited amount, with a maximum limit of 5% to protect users.
  * @param newFee The new fee percentage to be set, expressed in basis points (hundredths of a percent).
  * For example, to set a fee of 5%, `newFee` should be 500.
  */
  function setPlatformFee(uint256 newFee) external onlyOwner {
    require(newFee <= 500, 'Platform fee can not be greater than 5%');

    platformFee = newFee;
  }

  /**
  * @dev Creates a new distribution with the provided parameters.
  * @param tokenIN The address of the input token.
  * @param tokenOUT The address of the output token.
  * @param duration The duration of the distribution in seconds.
  * @param amountOUT The amount of output tokens to distribute.
  * @param name The name of the distribution.
  * @param description The description of the distribution.
  * @param ipfsHash The IPFS hash containing distribution details.
  * @param percentReturned The percentage of input tokens to be returned to the user.
  */
  function createDistribution(
    IERC20Metadata tokenIN,
    IERC20Metadata tokenOUT,
    uint256 duration,
    uint256 amountOUT,
    string calldata name,
    string calldata description,
    string calldata ipfsHash,
    uint256 percentReturned
  ) public payable {
    // Transfer tokensOUT from creator to contract for yield
    if (address(tokenOUT) != address(0)) {
      uint256 balanceBefore = tokenOUT.balanceOf(address(this));
      ERC20Helpers.safeTransferFrom(address(tokenOUT), msg.sender, address(this), amountOUT);
      require(tokenOUT.balanceOf(address(this)) - balanceBefore == amountOUT, "Incorrect number of tokens received");
      require(msg.value == 0, 'msg.value must be zero for distributions that do not use ETH for tokenOUT');
    } else require(amountOUT == msg.value, 'amountOUT and msg.value must be exactly the same');

    require(amountOUT / duration > 0, "Tokens per second must be greater than 0");
    require(percentReturned <= 10_000 - platformFee, "Percent returned must be less than or equal to 100% minus platformFee");

    distributions.push();
    //
    uint256 id = distributions.length;
    Distribution storage distribution = distributions[id - 1];
    userDistributions[msg.sender].push(id);

    if (newestActiveDistributionId != 0)
      distributions[newestActiveDistributionId - 1].prevActiveId = id;

    distribution.nextActiveId = newestActiveDistributionId;
    newestActiveDistributionId = id;


    distribution.tokensPerSecond = PRECISION * amountOUT / duration;
    distribution.percentReturned = percentReturned;
    distribution.platformFee = platformFee;
    distribution.amountOUT = amountOUT;
    distribution.creator = msg.sender;
    distribution.ipfsHash = ipfsHash;
    distribution.duration = duration;
    distribution.tokenOUT = tokenOUT;
    distribution.tokenIN = tokenIN;
    distribution.id = id;

    distribution.name = name;
    distribution.description = description;
    emit DistributionCreated(
      id,
      distribution.creator,
      name,
      description,
      duration,
      ipfsHash,
      amountOUT,
      percentReturned,
      address(tokenOUT),
      address(tokenIN)
    );
  }

  /**
  * @dev Retrieves token information such as contract address, symbol, name, and decimals.
  * @param token The token contract to retrieve information from.
  * @return TokenInfo Struct containing the token information.
  */
  function tokenInfo(IERC20Metadata token) public view returns (TokenInfo memory) {
    if (address(token) == address(0))
      return TokenInfo({
        contractAddress: address(0),
        name: 'Ethereum',
        symbol: 'ETH',
        decimals: 18
      });

    return TokenInfo({
      contractAddress: address(token),
      decimals: ERC20Helpers.tryDecimals(token),
      symbol: ERC20Helpers.trySymbol(token),
      name: ERC20Helpers.tryName(token)
    });
  }

  /**
  * @notice Gets distribution and user-specific information for a given distribution ID.
  * @param distributionId The ID of the distribution.
  * @param user The address of the user.
  * @return DistributionInfo Struct containing information about the distribution and the user's interaction with it.
  */
  function getInfo(uint256 distributionId, address user) public view returns (DistributionInfo memory) {
    require(distributionId > 0 && distributionId <= distributions.length, "Distribution ID is out of range");

    Distribution storage distribution = distributions[distributionId - 1];
    DistributionInfo memory info;

    info.distribution = distribution;
    info.currentTimestamp = block.timestamp;

    info.tokenOUT = tokenInfo(distribution.tokenOUT);
    info.tokenIN = tokenInfo(distribution.tokenIN);

    info.tokenOutPrice = ethPerToken(address(distribution.tokenOUT));
    info.tokenInPrice = ethPerToken(address(distribution.tokenIN));
    info.uncommonRewardId = distribution.uncommonRewardId;
    info.hasUncommonReward = distribution.hasUncommonReward;

    if (user != address(0)) {
      Deposit storage deposited = deposits[distributionId][user];
      info.userAllocated = allocatedAmount(distributionId, user);
      info.userHasClaimed = deposited.claimed;
      info.userDeposits = deposited.amount;
    }

    return info;
	}

  /**
  * @notice Retrieves distributions created or participated in by a specified user.
  * @dev Supports pagination and fetches distributions by user creation or deposits. It returns a subset of distributions based on the page
  *      and pageSize provided.
  * @param user User's address whose distributions are queried.
  * @param page Page number for result pagination.
  * @param pageSize Number of distribution entries per page.
  * @return results Array of `DistributionInfo` with details on each relevant distribution.
  */
  function getUserDistributions(address user, uint256 page, uint256 pageSize) public view returns (DistributionInfo[] memory) {
    uint256 total = userDistributions[user].length;
    uint256 startIndex = (page - 1) * pageSize;
    if (startIndex > total) startIndex = total;

    uint256 endIndex = startIndex + pageSize;
    if (endIndex > total) endIndex = total;

    uint256 resultCount = endIndex - startIndex;
    DistributionInfo[] memory results = new DistributionInfo[](resultCount);

    for (uint256 i = 0; i < resultCount; i++)
      results[i] = getInfo(userDistributions[user][startIndex + i], user);

    return results;
  }

  /**
  * @notice Retrieves a list of active distributions that haven't distributed rewards yet.
  * @dev Paginates active distributions based on page and pageSize parameters. This method dynamically calculates the number of
  *      active distributions available starting from the requested page and returns only those entries.
  * @param user Address of the user for context in the getInfo call.
  * @param page Page number, starting from 1.
  * @param pageSize Maximum number of entries per page.
  * @return results Array of `DistributionInfo` with details about each active distribution.
  */
  function getActiveDistributions(address user, uint256 page, uint256 pageSize) public view returns (DistributionInfo[] memory) {
    uint256 currentIndex = newestActiveDistributionId;
    uint256 skipped = 0;

    // Skip to the page's starting distribution
    while (currentIndex != 0 && skipped < (page - 1) * pageSize) {
      currentIndex = distributions[currentIndex - 1].nextActiveId;
      skipped++;
    }

    // Determine the size of the results array based on remaining active distributions
    uint256 remainingDistributions = 0;
    uint256 countIndex = currentIndex;
    while (countIndex != 0 && remainingDistributions < pageSize) {
      remainingDistributions++;
      countIndex = distributions[countIndex - 1].nextActiveId;
    }

    // Allocate the array with the correct number of elements
    DistributionInfo[] memory results = new DistributionInfo[](remainingDistributions);

    // Populate the results array
    uint256 count = 0;
    while (currentIndex != 0 && count < remainingDistributions) {
      results[count] = getInfo(currentIndex, user);
      currentIndex = distributions[currentIndex - 1].nextActiveId;
      count++;
    }

    return results;
  }


  /**
  * @dev Returns a list of recent distributions with pagination.
  * @param user The user address to include in the distribution info.
  * @param page The page number to fetch.
  * @param pageSize The number of items per page.
  * @return An array of DistributionInfo structs.
  */
  function getRecentDistributions(address user, uint256 page, uint256 pageSize) external view returns (DistributionInfo[] memory) {
    uint256 totalDistributions = distributions.length;

    // Calculate the starting index
    uint256 startIndex = ((page - 1) * pageSize);
    if (startIndex > totalDistributions)
      startIndex = totalDistributions;

    // Calculate the number of items to return
    uint256 endIndex = startIndex + pageSize;
    if (endIndex > totalDistributions)
      endIndex = totalDistributions;

    uint256 resultCount = endIndex - startIndex;
    DistributionInfo[] memory recentDistributions = new DistributionInfo[](resultCount);

    // Iterate over the distributions array in reverse order and fill the result array
    for (uint256 i = 0; i < resultCount; i++)
      recentDistributions[i] = getInfo(totalDistributions - startIndex - i, user);

    return recentDistributions;
  }

  /**
  * @dev Starts the distribution process by setting the start and end times.
  * @param distribution The distribution to start.
  */
  function startDistribution(Distribution storage distribution) private {
    distribution.startTime = block.timestamp;
    distribution.endTime = distribution.startTime + distribution.duration;
  }

  /**
  * @dev Allows a user to deposit into a distribution, starting the distribution if necessary.
  * @param distributionId The ID of the distribution to deposit into.
  * @param amount The amount to deposit.
  */
  function deposit(uint256 distributionId, uint256 amount) external payable nonReentrant {
    Distribution storage distribution = distributions[distributionId - 1];
    if (distribution.startTime == 0) startDistribution(distribution);
    require(block.timestamp <= distribution.endTime, "Distribution period has ended");
    require(deposits[distributionId][msg.sender].amount == 0, "Can only deposit once");

    if (address(distribution.tokenIN) != address(0)) {
      require(msg.value == 0, "Cannot send ETH to token-based distribution");
      ERC20Helpers.safeTransferFrom(address(distribution.tokenIN), msg.sender, address(this), amount);
    } else require(amount == msg.value, "deposit amount and msg.value must be exactly the same");

    require(amount > 0, "Cannot deposit zero tokens");

    uint256 elapsedTime = block.timestamp - distribution.lastDepositAt;

    if (distribution.lastDepositAt > 0)
      distribution.totalTokensPerDeposit += elapsedTime * distribution.tokensPerSecond / distribution.totalDeposited;

    deposits[distributionId][msg.sender] = Deposit({
      previouslyAllocated: distribution.totalTokensPerDeposit,
      amount: amount,
      claimed: false
    });

    distribution.totalDeposited += amount;
    distribution.lastDepositAt = block.timestamp;

    if (distribution.creator != msg.sender)
      userDistributions[msg.sender].push(distributionId);

    emit Deposited(distributionId, msg.sender, amount);
  }

  /**
  * @dev Distributes the reward for a distribution after the distribution period has ended.
  * @param distributionId The ID of the distribution whose rewards are to be distributed.
  */
  function distributeReward(uint256 distributionId) external nonReentrant {
    Distribution storage distribution = distributions[distributionId - 1];
    require(block.timestamp > distribution.endTime, "Distribution period has not yet ended");
    _distributeReward(distribution);
  }

  /**
  * @dev Internal function to distribute rewards for a distribution.
  * @param distribution The distribution whose rewards are to be distributed.
  */
  function _distributeReward(Distribution storage distribution) internal {
    if (distribution.rewardDistributed) return;
    distribution.rewardDistributed = true;

    // Remove from active list
    if (distribution.prevActiveId != 0)
      distributions[distribution.prevActiveId - 1].nextActiveId = distribution.nextActiveId;

    if (distribution.nextActiveId != 0)
      distributions[distribution.nextActiveId - 1].prevActiveId = distribution.prevActiveId;

    if (newestActiveDistributionId == distribution.id)
      newestActiveDistributionId = distribution.nextActiveId;

    uint256 rewardAmount = distribution.platformFee * distribution.totalDeposited / 10_000;
    uint256 uncommonRewardLength = rewardFarmers.uncommonRewardCount();

    if (address(distribution.tokenIN) == address(0))
      rewardFarmers.addRewards{value: rewardAmount}(distribution.id, address(0), rewardAmount);
    else {
      ERC20Helpers.safeApprove(address(distribution.tokenIN), address(rewardFarmers), rewardAmount);
      rewardFarmers.addRewards(distribution.id, address(distribution.tokenIN), rewardAmount);
      if (uncommonRewardLength != rewardFarmers.uncommonRewardCount()) {
        distribution.uncommonRewardId = uncommonRewardLength;
        distribution.hasUncommonReward = true;
      }
    }
  }

  /**
  * @dev Allows the creator of a distribution to withdraw the input tokens after the distribution has ended.
  * @param distributionId The ID of the distribution to withdraw from.
  */
  function withdraw(uint256 distributionId) external nonReentrant {
    Distribution storage distribution = distributions[distributionId - 1];
    require(msg.sender == distribution.creator, "Only the creator can withdraw the received tokens");
    require(block.timestamp > distribution.endTime, "Distribution period has not yet ended");
    require(!distribution.ownerWithdrawn, "Creator has already withdrawn");
    distribution.ownerWithdrawn = true;
    _distributeReward(distribution);

    uint256 rewardAmount = distribution.platformFee * distribution.totalDeposited / 10_000;
    uint256 amountIn = (10_000 - distribution.percentReturned) * distribution.totalDeposited / 10_000;
    amountIn -= rewardAmount;

    if (address(distribution.tokenIN) == address(0))
      payable(msg.sender).transfer(amountIn);
    else ERC20Helpers.safeTransfer(address(distribution.tokenIN), msg.sender, amountIn);

  }

  /**
  * @dev Allows a user to claim their rewards after the distribution period has ended.
  * @param distributionId The ID of the distribution from which to claim rewards.
  */
  function claim(uint256 distributionId) external nonReentrant {
    Distribution storage distribution = distributions[distributionId - 1];
    require(block.timestamp > distribution.endTime, "Distribution period has not yet ended");

    _distributeReward(distribution);

    Deposit storage userDeposit = deposits[distributionId][msg.sender];
    require(!userDeposit.claimed, "Already claimed");
    userDeposit.claimed = true;

    uint256 yieldAmount = allocatedAmount(distributionId, msg.sender);
    uint256 amountReturned = userDeposit.amount * distribution.percentReturned / 10_000;

    if (address(distribution.tokenOUT) == address(0))
      payable(msg.sender).transfer(yieldAmount);
    else ERC20Helpers.safeTransfer(address(distribution.tokenOUT), msg.sender, yieldAmount);

    if (address(distribution.tokenIN) == address(0))
      payable(msg.sender).transfer(amountReturned);
    else ERC20Helpers.safeTransfer(address(distribution.tokenIN), msg.sender, amountReturned);

    emit Claim(distributionId, msg.sender, yieldAmount, amountReturned);
  }

  /**
  * @dev Calculates the current allocation period for a distribution.
  * @param distributionId The ID of the distribution.
  * @return The current allocation period in seconds.
  */
  function currentAllocationPeriod(uint256 distributionId) public view returns (uint256) {
    Distribution storage distribution = distributions[distributionId - 1];
    if (distribution.endTime < block.timestamp)
      return distribution.endTime - distribution.lastDepositAt;
    else return block.timestamp - distribution.lastDepositAt;
  }

  /**
  * @dev Calculates the total allocated amount for a user in a distribution.
  * @param distributionId The ID of the distribution.
  * @param user The address of the user.
  * @return The total allocated amount for the user.
  */
  function allocatedAmount(uint256 distributionId, address user) public view returns (uint256) {
    Distribution storage distribution = distributions[distributionId - 1];
    if (distribution.totalDeposited == 0) return 0;
    Deposit storage deposited = deposits[distributionId][user];
    uint256 currentAllocationAmount = currentAllocationPeriod(distributionId) * distribution.tokensPerSecond * deposited.amount / distribution.totalDeposited;
    uint256 previousAllocationAmount = deposited.amount * (distribution.totalTokensPerDeposit - deposited.previouslyAllocated);

    return (previousAllocationAmount + currentAllocationAmount) / PRECISION;
  }

  /**
  * @dev Calculates the current allocation for a user in a distribution.
  * @param distributionId The ID of the distribution.
  * @param user The user's address.
  * @return The current allocation for the user.
  */
  function currentAllocation(uint256 distributionId, address user) public view returns (uint256) {
    Distribution storage distribution = distributions[distributionId - 1];
    if (distribution.totalDeposited == 0) return 0;
    Deposit storage deposited = deposits[distributionId][user];
    return currentAllocationPeriod(distributionId) * distribution.tokensPerSecond * deposited.amount / distribution.totalDeposited;
  }

  /**
  * @dev Calculates the previous allocation for a user in a distribution.
  * @param distributionId The ID of the distribution.
  * @param user The user's address.
  * @return The previous allocation for the user.
  */
  function previousAllocation(uint256 distributionId, address user) public view returns (uint256) {
    Distribution storage distribution = distributions[distributionId - 1];
    if (distribution.totalDeposited == 0) return 0;
    Deposit storage deposited = deposits[distributionId][user];
    return deposited.amount * (distribution.totalTokensPerDeposit - deposited.previouslyAllocated);
  }

  /**
  * @dev Retrieves the current exchange rate of a token to ETH.
  * @param token The address of the token.
  * @return The exchange rate of the token to ETH.
  */
  function ethPerToken(address token) public view returns (uint) {
    return rewardFarmers.ethPerToken(token);
  }
}

File 2 of 11 : ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

File 3 of 11 : ERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";

/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the default value returned by this function, unless
     * it's overridden.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(address from, address to, uint256 amount) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

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

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}
}

File 4 of 11 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 5 of 11 : IRewardFarmers.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

interface IRewardFarmers {
  // Define method signatures that are used in the RiceFields contract

  // Assuming addRewards is a function called on rewardFarmers
  function addRewards(uint256 distributionId, address token, uint256 amount) external payable;

  // Assuming uncommonRewardCount is a function called on rewardFarmers
  function uncommonRewardCount() external view returns (uint256);

  // Assuming ethPerToken is a function called on rewardFarmers
  function ethPerToken(address token) external view returns (uint256);
}

File 6 of 11 : ERC20Helpers.sol
// SPDX-License-Identifier: GPL-3.0-or-later
import "@openzeppelin/contracts/interfaces/IERC20Metadata.sol";

pragma solidity >=0.6.0;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library ERC20Helpers {
  function safeApprove(
    address token,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('approve(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      'ERC20Helpers::safeApprove: approve failed'
    );
  }

  function safeTransfer(
    address token,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('transfer(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      'ERC20Helpers::safeTransfer: transfer failed'
    );
  }

  function safeTransferFrom(
    address token,
    address from,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      'ERC20Helpers::transferFrom: transferFrom failed'
    );
  }

  function safeTransferETH(address to, uint256 value) internal {
    (bool success, ) = to.call{value: value}(new bytes(0));
    require(success, 'ERC20Helpers::safeTransferETH: ETH transfer failed');
  }

  /**
  * @dev Tries to fetch the decimals of the given token, defaults to 0 if undefined.
  * @param token The token contract to retrieve decimals from.
  * @return The number of decimals of the token.
  */
  function tryDecimals(IERC20Metadata token) internal view returns (uint8) {
    try token.decimals{gas: 20000}() returns (uint8 value) {
      return value;
    } catch {
      return 18; // Default value
    }
  }

  /**
  * @dev Tries to fetch the symbol of the given token, defaults to "UNKNOWN" if undefined.
  * @param token The token contract to retrieve the symbol from.
  * @return The symbol of the token.
  */
  function trySymbol(IERC20Metadata token) internal view returns (string memory) {
    try token.symbol{gas: 20000}() returns (string memory value) {
      return value;
    } catch {
      return "UNKNOWN"; // Default value
    }
  }

  /**
  * @dev Tries to fetch the name of the given token, defaults to "Unknown Token" if undefined.
  * @param token The token contract to retrieve the name from.
  * @return The name of the token.
  */
  function tryName(IERC20Metadata token) internal view returns (string memory) {
    try token.name{gas: 20000}() returns (string memory value) {
      return value;
    } catch {
      return "Unknown Token"; // Default value
    }
  }

}

File 7 of 11 : IFARM.sol
pragma solidity ^0.8.12;

interface IFARM {
  function activateRewards(address _uniswapPair, address _weth, address _router) external;
}

File 8 of 11 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

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

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 9 of 11 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";

/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

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

File 10 of 11 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol)

pragma solidity ^0.8.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 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.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 11 of 11 : IERC20Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20Metadata.sol)

pragma solidity ^0.8.0;

import "../token/ERC20/extensions/IERC20Metadata.sol";

Settings
{
  "remappings": [
    "@ensdomains/=node_modules/@ensdomains/",
    "@ganache/=node_modules/@ganache/",
    "@openzeppelin/=node_modules/@openzeppelin/",
    "@truffle/=node_modules/@truffle/",
    "@uniswap/=node_modules/@uniswap/",
    "hardhat/=node_modules/hardhat/",
    "truffle/=node_modules/truffle/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "paris",
  "viaIR": true,
  "libraries": {}
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"contract IRewardFarmers","name":"_farm","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"distributionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethAmount","type":"uint256"}],"name":"Claim","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"distributionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"},{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"description","type":"string"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"},{"indexed":false,"internalType":"string","name":"ipfsHash","type":"string"},{"indexed":false,"internalType":"uint256","name":"amountOUT","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"percentReturned","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenOUT","type":"address"},{"indexed":false,"internalType":"address","name":"tokenIN","type":"address"}],"name":"DistributionCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"allocatedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"uint256","name":"percentReturned","type":"uint256"}],"name":"createDistribution","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"currentAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"currentAllocationPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"previouslyAllocated","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"distributeReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distributionCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"distributions","outputs":[{"internalType":"uint256","name":"totalTokensPerDeposit","type":"uint256"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"percentReturned","type":"uint256"},{"internalType":"uint256","name":"tokensPerSecond","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"bool","name":"rewardDistributed","type":"bool"},{"internalType":"uint256","name":"lastDepositAt","type":"uint256"},{"internalType":"bool","name":"ownerWithdrawn","type":"bool"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"nextActiveId","type":"uint256"},{"internalType":"uint256","name":"prevActiveId","type":"uint256"},{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"ethPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getActiveDistributions","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"totalTokensPerDeposit","type":"uint256"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"percentReturned","type":"uint256"},{"internalType":"uint256","name":"tokensPerSecond","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"bool","name":"rewardDistributed","type":"bool"},{"internalType":"uint256","name":"lastDepositAt","type":"uint256"},{"internalType":"bool","name":"ownerWithdrawn","type":"bool"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"nextActiveId","type":"uint256"},{"internalType":"uint256","name":"prevActiveId","type":"uint256"},{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"}],"internalType":"struct RiceFields.Distribution","name":"distribution","type":"tuple"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"userAllocated","type":"uint256"},{"internalType":"uint256","name":"tokenOutPrice","type":"uint256"},{"internalType":"uint256","name":"tokenInPrice","type":"uint256"},{"internalType":"uint256","name":"userDeposits","type":"uint256"},{"internalType":"bool","name":"userHasClaimed","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenOUT","type":"tuple"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenIN","type":"tuple"},{"internalType":"uint256","name":"rewardId","type":"uint256"}],"internalType":"struct RiceFields.DistributionInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getInfo","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"totalTokensPerDeposit","type":"uint256"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"percentReturned","type":"uint256"},{"internalType":"uint256","name":"tokensPerSecond","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"bool","name":"rewardDistributed","type":"bool"},{"internalType":"uint256","name":"lastDepositAt","type":"uint256"},{"internalType":"bool","name":"ownerWithdrawn","type":"bool"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"nextActiveId","type":"uint256"},{"internalType":"uint256","name":"prevActiveId","type":"uint256"},{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"}],"internalType":"struct RiceFields.Distribution","name":"distribution","type":"tuple"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"userAllocated","type":"uint256"},{"internalType":"uint256","name":"tokenOutPrice","type":"uint256"},{"internalType":"uint256","name":"tokenInPrice","type":"uint256"},{"internalType":"uint256","name":"userDeposits","type":"uint256"},{"internalType":"bool","name":"userHasClaimed","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenOUT","type":"tuple"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenIN","type":"tuple"},{"internalType":"uint256","name":"rewardId","type":"uint256"}],"internalType":"struct RiceFields.DistributionInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getRecentDistributions","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"totalTokensPerDeposit","type":"uint256"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"percentReturned","type":"uint256"},{"internalType":"uint256","name":"tokensPerSecond","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"bool","name":"rewardDistributed","type":"bool"},{"internalType":"uint256","name":"lastDepositAt","type":"uint256"},{"internalType":"bool","name":"ownerWithdrawn","type":"bool"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"nextActiveId","type":"uint256"},{"internalType":"uint256","name":"prevActiveId","type":"uint256"},{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"}],"internalType":"struct RiceFields.Distribution","name":"distribution","type":"tuple"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"userAllocated","type":"uint256"},{"internalType":"uint256","name":"tokenOutPrice","type":"uint256"},{"internalType":"uint256","name":"tokenInPrice","type":"uint256"},{"internalType":"uint256","name":"userDeposits","type":"uint256"},{"internalType":"bool","name":"userHasClaimed","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenOUT","type":"tuple"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenIN","type":"tuple"},{"internalType":"uint256","name":"rewardId","type":"uint256"}],"internalType":"struct RiceFields.DistributionInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"page","type":"uint256"},{"internalType":"uint256","name":"pageSize","type":"uint256"}],"name":"getUserDistributions","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"totalTokensPerDeposit","type":"uint256"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"percentReturned","type":"uint256"},{"internalType":"uint256","name":"tokensPerSecond","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"totalDeposited","type":"uint256"},{"internalType":"bool","name":"rewardDistributed","type":"bool"},{"internalType":"uint256","name":"lastDepositAt","type":"uint256"},{"internalType":"bool","name":"ownerWithdrawn","type":"bool"},{"internalType":"uint256","name":"platformFee","type":"uint256"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"amountOUT","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"string","name":"ipfsHash","type":"string"},{"internalType":"address","name":"creator","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint256","name":"nextActiveId","type":"uint256"},{"internalType":"uint256","name":"prevActiveId","type":"uint256"},{"internalType":"contract IERC20Metadata","name":"tokenIN","type":"address"},{"internalType":"contract IERC20Metadata","name":"tokenOUT","type":"address"}],"internalType":"struct RiceFields.Distribution","name":"distribution","type":"tuple"},{"internalType":"uint256","name":"uncommonRewardId","type":"uint256"},{"internalType":"uint256","name":"currentTimestamp","type":"uint256"},{"internalType":"bool","name":"hasUncommonReward","type":"bool"},{"internalType":"uint256","name":"userAllocated","type":"uint256"},{"internalType":"uint256","name":"tokenOutPrice","type":"uint256"},{"internalType":"uint256","name":"tokenInPrice","type":"uint256"},{"internalType":"uint256","name":"userDeposits","type":"uint256"},{"internalType":"bool","name":"userHasClaimed","type":"bool"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenOUT","type":"tuple"},{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"tokenIN","type":"tuple"},{"internalType":"uint256","name":"rewardId","type":"uint256"}],"internalType":"struct RiceFields.DistributionInfo[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newestActiveDistributionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"previousAllocation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"setPlatformFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Metadata","name":"token","type":"address"}],"name":"tokenInfo","outputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"decimals","type":"uint256"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct RiceFields.TokenInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"userDistributions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"distributionId","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60803460b957601f61317738819003918201601f19168301916001600160401b0383118484101760be5780849260209460405283398101031260b957516001600160a01b03908181169081900360b957600160005560015460018060a01b0319903382821617600155604051933391167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3670de0b6b3a7640000600255606460085560035416176003556130a290816100d58239f35b600080fd5b634e487b7160e01b600052604160045260246000fdfe610200604052600436101561001357600080fd5b60003560e01c8062d5397814611a915780630a1047e314611a735780630f2cba8314611a1b57806312e8e2c31461199c57806326232a2e1461197e5780632d9043b1146119585780632e1a7d4d146117bd578063379607f51461161b5780634487d3df146113e757806353a58de11461138357806361c0a6ec1461135d57806362436c931461133757806364089c4a14611249578063715018a6146111ec5780637c06e82e1461112f5780638c81bc24146111115780638da5cb5b146110e85780638f8f963e14610fc2578063940a4e4514610f72578063aaf5eb6814610f54578063b8e86aa514610f29578063c65c3d9514610f0b578063e2bbb15814610b85578063eff3379514610244578063f2fde38b1461017b5763f5dab7111461013a57600080fd5b346101765760203660031901126101765761017261015e610159611ae2565b612768565b604051918291602083526020830190611b40565b0390f35b600080fd5b3461017657602036600319011261017657610194611ae2565b61019c612826565b6001600160a01b039081169081156101f057600154826bffffffffffffffffffffffff60a01b821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61010036600319011261017657610259611ae2565b610261611acc565b6084356001600160401b03811161017657610280903690600401611fd1565b91909260a4356001600160401b038111610176576102a2903690600401611fd1565b6001600160401b0360c49692963511610176576102c43660c435600401611fd1565b90929091906001600160a01b03861615610b1e576040516370a0823160e01b81523060048201526020816024816001600160a01b038b165afa908115610ae057600091610aec575b5061032460643530336001600160a01b038b16612d9e565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b038c165afa918215610ae057600092610aaa575b506103679060643592612146565b03610a5957346109dc575b61038060443560643561240c565b156109865760085461271080828103116108f7570360e4351161090d5760065496600160401b88101561073957600188016006556103bd88611da3565b50506001880188116108f7576103d288611da3565b503360005260076020526103ed60018a0160406000206126f7565b600554806108cf575b5060055460138201556001890160055561041f60443561041a6064356002546123f9565b61240c565b600382015560e43560028201556008546009820155606435600b820155600f810180546001600160a01b031916331790556001600160401b0385116107395761046b600e820154611dde565b601f8111610888575b50846000601f821160011461081a5760009161080f575b508560011b906000198760031b1c191617600e8201555b604435600c8201556016810180546001600160a01b038a81166001600160a01b031992831617909255601583018054928a16929091169190911790556001890160108201556001600160401b038211610739576105026012820154611dde565b601f81116107c8575b50816000601f821160011461075a5760009161074f575b508260011b906000198460031b1c19161760128201555b6001600160401b038411610739576105546011820154611dde565b601f81116106f2575b506000601f851160011461064c57936105ef61061396946105fd9460017f9a072e55ca460e89cc4a516d2b7cf4f8d542ac9a825dd702ef1783c8d771fdbc9e958560409f9e9d9c9a600091610641575b50600019600388901b1c191686831b1760118201555b600f828060a01b03910154169c8e519e8f9e8f90610140948594018252602082015201528c019161272c565b9189830360608b015261272c565b91604435608088015286830360a088015261272c565b60643560c085015260e43560e08501526001600160a01b0392831661010085015291166101208301520390a1005b9050870135386105ad565b6011820160005260206000209060005b601f19871681106106da575061061396946105fd9460017f9a072e55ca460e89cc4a516d2b7cf4f8d542ac9a825dd702ef1783c8d771fdbc9e95899560409f9e9d9c9a956105ef96601f198116106106c0575b50508186811b0160118201556105c3565b880135600019600389901b60f8161c1916905538806106af565b90916020600181928f8601358155019301910161065c565b601182016000526020600020601f860160051c810160208710610732575b601f830160051c8201811061072657505061055d565b60008155600101610710565b5080610710565b634e487b7160e01b600052604160045260246000fd5b90508301358b610522565b90506012820160005260206000209060005b601f19851681106107b0575083601f19811610610796575b5050600182811b016012820155610539565b840135600019600385901b60f8161c191690558a80610784565b9091602060018192858901358155019301910161076c565b601282016000526020600020601f840160051c810160208510610808575b601f830160051c820181106107fc57505061050b565b600081556001016107e6565b50806107e6565b90508601358b61048b565b9050600e820160005260206000209060005b601f1988168110610870575086601f19811610610856575b5050600185811b01600e8201556104a2565b870135600019600388901b60f8161c191690558a80610844565b9091602060018192858c01358155019301910161082c565b600e82016000526020600020601f870160051c8101602088106108c8575b601f830160051c820181106108bc575050610474565b600081556001016108a6565b50806108a6565b806000198101116108f7576108e79060001901611da3565b50601460018b019101558a6103f6565b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152604560248201527f50657263656e742072657475726e6564206d757374206265206c65737320746860448201527f616e206f7220657175616c20746f2031303025206d696e757320706c6174666f606482015264726d46656560d81b608482015260a490fd5b60405162461bcd60e51b815260206004820152602860248201527f546f6b656e7320706572207365636f6e64206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608490fd5b60405162461bcd60e51b815260206004820152604960248201527f6d73672e76616c7565206d757374206265207a65726f20666f7220646973747260448201527f69627574696f6e73207468617420646f206e6f74207573652045544820666f72606482015268081d1bdad95b93d55560ba1b608482015260a490fd5b60405162461bcd60e51b815260206004820152602360248201527f496e636f7272656374206e756d626572206f6620746f6b656e732072656365696044820152621d995960ea1b6064820152608490fd5b9091506020813d602011610ad8575b81610ac660209383611e7d565b81010312610176575190610367610359565b3d9150610ab9565b6040513d6000823e3d90fd5b90506020813d602011610b16575b81610b0760209383611e7d565b8101031261017657518961030c565b3d9150610afa565b60643534146103725760405162461bcd60e51b815260206004820152603060248201527f616d6f756e744f555420616e64206d73672e76616c7565206d7573742062652060448201526f65786163746c79207468652073616d6560801b6064820152608490fd5b6040366003190112610176576004356024803590610ba161287e565b6000198301838111610ef657610bb690611da3565b50600a8101805415610eda575b50600d8101544211610e965783600052602091600483526040600020336000528352600160406000200154610e5b5760158201546001600160a01b03919082168015610df25734610d9a5785610c1c9130903390612d9e565b8415610d575760078301908154610c338142612146565b90610d28575b5083546040519160608301908382106001600160401b03831117610d145750604052815260028582019187835260408101926000845289600052600488526040600020336000528852604060002091518255516001820155019051151560ff8019835416911617905560058301610cb18682546124f4565b9055429055600f339201541603610cf9575b6040519283528201527f1599c0fcf897af5babc2bfcf707f5dc050f841b044d97c3251ecec35b9abf80b60403392a26001600055005b3360005260078152610d0f8360406000206126f7565b610cc3565b634e487b7160e01b60009081526041600452fd5b610d48610d3d610d4f926003880154906123f9565b60058701549061240c565b85546124f4565b845587610c39565b83601a6064926040519262461bcd60e51b845260048401528201527f43616e6e6f74206465706f736974207a65726f20746f6b656e730000000000006044820152fd5b60405162461bcd60e51b815260048101869052602b818401527f43616e6e6f742073656e642045544820746f20746f6b656e2d6261736564206460448201526a34b9ba3934b13aba34b7b760a91b6064820152608490fd5b50348514610c1c578360356084926040519262461bcd60e51b845260048401528201527f6465706f73697420616d6f756e7420616e64206d73672e76616c7565206d7573604482015274742062652065786163746c79207468652073616d6560581b6064820152fd5b8260156064926040519262461bcd60e51b845260048401528201527443616e206f6e6c79206465706f736974206f6e636560581b6044820152fd5b60405162461bcd60e51b815260206004820152601d818401527f446973747269627574696f6e20706572696f642068617320656e6465640000006044820152606490fd5b429055610eeb600c820154426124f4565b600d82015584610bc3565b50634e487b7160e01b60009081526011600452fd5b34610176576000366003190112610176576020600654604051908152f35b34610176576020366003190112610176576020610f4c610f47611ae2565b612688565b604051908152f35b34610176576000366003190112610176576020600254604051908152f35b3461017657602036600319011261017657600435610f8e61287e565b60001981019081116108f757610fa6610fbb91611da3565b50610fb6600d820154421161249a565b6128d4565b6001600055005b3461017657610fd036611f43565b600554926000935b801515806110ca575b1561100f5760001981019081116108f757601361100061100992611da3565b50015494612679565b93610fd8565b60009181925b831515806110c1575b1561104d5761102c90612679565b9260001981019081116108f757611044601391611da3565b50015492611015565b9061105782612615565b906000935b801515806110b8575b156110aa576110748282612153565b61107e8685612665565b526110898584612665565b5060001981019081116108f75760136110006110a492611da3565b9361105c565b604051806101728582611f6d565b50838510611065565b5084811061101e565b5060001984018481116108f757836110e1916123f9565b8510610fe1565b34610176576000366003190112610176576001546040516001600160a01b039091168152602090f35b34610176576000366003190112610176576020600554604051908152f35b346101765761113d36611f43565b60065492909160001981019081116108f75782611159916123f9565b918383116111e4575b61116c90836124f4565b828482116111dc575b61117e91612146565b9161118883612615565b9360005b8481106111a157604051806101728882611f6d565b806111c0856111bb6001946111b68888612146565b612146565b612153565b6111ca8289612665565b526111d58188612665565b500161118c565b849150611175565b839250611162565b3461017657600036600319011261017657611205612826565b600180546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346101765761125736611f43565b9160018060a01b0381169283600052600760209360076020526040600020549060001981019081116108f7578361128d916123f9565b9281841161132d575b6112b4916112a58592836124f4565b90808211611325575b50612146565b936112be85612615565b9560005b8681106112d757604051806101728a82611f6d565b60019082600052848452611309876112fd60406000206112f7858b6124f4565b90611d75565b90549060031b1c612153565b611313828b612665565b5261131e818a612665565b50016112c2565b9050886112ae565b9092508290611296565b34610176576040366003190112610176576020610f4c611355611acc565b60043561259d565b34610176576040366003190112610176576020610f4c61137b611acc565b600435612501565b346101765760403660031901126101765761139c611acc565b600435600052600460205260406000209060018060a01b03166000526020526060604060002080549060ff600260018301549201541690604051928352602083015215156040820152f35b34610176576020366003190112610176576004356006548110156101765761140e90611da3565b506101e081905280546001820154600283015461010052600383015461012052600483015460ff9081166101c05260058401546006850154600786015460088701546009880154600a890154600b8a0154600c8b0154600d8c01546115e39c6115cd9c6115a39b90999298939794969481169392169061149090600e01611e9e565b6101e051600f8101546001600160a01b031660805260108101549d919b91906114bb90601101611e9e565b610180526114ce60126101e05101611e9e565b6101a05260136101e051015460e05260146101e05101546101605260018060a01b0360156101e0510154166101405260018060a01b0360166101e05101541660c05260405160a0526102e09a60a05152602060a051015261010051604060a051015261012051606060a05101526101c0511515608060a051015260a080510152151560c060a051015260e060a0510152151561010060a051015261012060a051015261014060a051015261016060a051015261018060a05101526101a060a0510152806101c060a051015260a0510190611b1b565b906080516101e060a051015261020060a051015260a051810361022060a051015261018051611b1b565b60a051810361024060a05101526101a051611b1b565b60e05161026060a05101526101605161028060a0510152610140516102a060a051015260c0516102c060a051015260a051900360a051f35b346101765760203660031901126101765760043561163761287e565b60001981018181116108f75761164c90611da3565b5061165c600d820154421161249a565b611665816128d4565b816000526004602052604060002033600052602052604060002060028101805460ff81166117865760019060ff19161790556127106116b760016116a93387612501565b9301546002850154906123f9565b6016840154919004926001600160a01b03918390831680611772575060008115611769575b600080809381933390f115610ae0576015905b015416828161175957905060008115611750575b600080809381933390f115610ae0575b604051928352602083015260408201527fd27486cbbd902c694ff070c4b52eb23c8f7828d3688bd3c7293638daec28880860603392a26001600055005b506108fc611703565b611764913390612cbd565b611713565b506108fc6116dc565b60159291611781913390612cbd565b6116ef565b60405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606490fd5b34610176576020366003190112610176576004356117d961287e565b60001981019081116108f7576117ee90611da3565b50600f8101546001600160a01b0390811633036118f957611814600d830154421161249a565b60088201805460ff81166118b45760ff19166001179055611834826128d4565b60098201546005830154809161184e6127109384926123f9565b0460028501548303928084116108f75761186d611873936015956123f9565b04612146565b92015416806118a3575060008080809381811561189a575b3390f115610ae0576001600055005b506108fc61188b565b906118af913390612cbd565b610fbb565b60405162461bcd60e51b815260206004820152601d60248201527f43726561746f722068617320616c72656164792077697468647261776e0000006044820152606490fd5b60405162461bcd60e51b815260206004820152603160248201527f4f6e6c79207468652063726561746f722063616e2077697468647261772074686044820152706520726563656976656420746f6b656e7360781b6064820152608490fd5b34610176576040366003190112610176576020610f4c611976611acc565b60043561242c565b34610176576000366003190112610176576020600854604051908152f35b34610176576020366003190112610176576004356119b8612826565b6101f481116119c657600855005b60405162461bcd60e51b815260206004820152602760248201527f506c6174666f726d206665652063616e206e6f742062652067726561746572206044820152667468616e20352560c81b6064820152608490fd5b3461017657604036600319011261017657611a34611ae2565b6001600160a01b031660009081526007602052604090208054602435919082101561017657602091611a6591611d75565b90546040519160031b1c8152f35b34610176576020366003190112610176576020610f4c6004356123b9565b3461017657604036600319011261017657610172611ab8611ab0611acc565b600435612153565b604051918291602083526020830190611b89565b602435906001600160a01b038216820361017657565b600435906001600160a01b038216820361017657565b60005b838110611b0b5750506000910152565b8181015183820152602001611afb565b90602091611b3481518092818552858086019101611af8565b601f01601f1916010190565b611b869160018060a01b038251168152602082015160208201526060611b756040840151608060408501526080840190611b1b565b920151906060818403910152611b1b565b90565b9061016080611d6c611d5885516101808652805161018087015260208101516101a087015260408101516101c087015260608101516101e08701526080810151151561020087015260a081015161022087015260c0810151151561024087015260e081015161026087015261010081015115156102808701526101208101516102a08701526101408101516102c0870152611c59848201516102e090818901526101808301516103008901526101a08301516103208901526101c083015190610340890152610460880190611b1b565b6101e08201516001600160a01b0390811661036089015261020083015161038089015261022083015188830361017f199081016103a08b015291926102c092611cbe929091611ca791611b1b565b90610240860151908b8303016103c08c0152611b1b565b926102608101516103e08a01526102808101516104008a0152826102a0820151166104208a015201511661044087015260208701516020870152604087015160408701526060870151151560608701526080870151608087015260a087015160a087015260c087015160c087015260e087015160e08701526101008701511515610100870152610120870151868203610120880152611b40565b610140860151858203610140870152611b40565b93015191015290565b8054821015611d8d5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b600654811015611d8d576017906006600052027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600090565b90600182811c92168015611e0e575b6020831014611df857565b634e487b7160e01b600052602260045260246000fd5b91607f1691611ded565b608081019081106001600160401b0382111761073957604052565b6102e081019081106001600160401b0382111761073957604052565b6001600160401b03811161073957604052565b604081019081106001600160401b0382111761073957604052565b90601f801991011681019081106001600160401b0382111761073957604052565b90604051918260008254611eb181611dde565b90818452602094600191600181169081600014611f215750600114611ee2575b505050611ee092500383611e7d565b565b600090815285812095935091905b818310611f09575050611ee09350820101388080611ed1565b85548884018501529485019487945091830191611ef0565b92505050611ee094925060ff191682840152151560051b820101388080611ed1565b6060906003190112610176576004356001600160a01b038116810361017657906024359060443590565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b848310611fa35750505050505090565b9091929394958480611fc1600193603f198682030187528a51611b89565b9801930193019194939290611f93565b9181601f84011215610176578235916001600160401b038311610176576020838186019501011161017657565b6040519061200b82611e18565b6060808360008152600060208201528160408201520152565b6040519061018082018281106001600160401b0382111761073957806040526101608361205083611e33565b600092838152836101a0830152836101c0830152836101e08301528361020083015283610220830152836102408301528361026083015283610280830152836102a0830152836102c0830152836102e083015283610300830152836103208301526060610340830152836103608301528361038083015260606103a083015260606103c0830152836103e083015283610400830152836104208301528361044083015281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015261212e611ffe565b61012082015261213c611ffe565b6101408201520152565b919082039182116108f757565b9061215c612024565b50811515806123ad575b156123685760001982018281116108f75761218090611da3565b509161218a612024565b9260405161219781611e33565b815481526001820154806020830152600283015460408301526003830154606083015260ff600484015416151590816080840152600584015460a084015260ff600685015416151560c0840152600784015460e084015261230060ff60088601541694610100951515868601526122f66009820154956101209687820152600a8301546101409081830152600b840154610160830152600c840154610180830152600d8401546101a083015261224f600e8501611e9e565b6101c0830152600f8401546001600160a01b039081166101e084015260108501546102008401529761228360118601611e9e565b61022084015261229560128601611e9e565b610240840152601385015461026084015260148501546102808401528860168160158801541696876102a087015201541692836102c08201528d528c6040429101526122e083612768565b908d01526122ed84612768565b908c0152612688565b60a08a0152612688565b60c08801526020870152606086015283168061231e575b5050505090565b60019361234591846000526004602052604060002090600052602052604060002093612501565b608085015260ff600283015416151590840152015460e082015238808080612317565b60405162461bcd60e51b815260206004820152601f60248201527f446973747269627574696f6e204944206973206f7574206f662072616e6765006044820152606490fd5b50600654821115612166565b60001981019081116108f7576123ce90611da3565b50600d810154428110156123ea576007611b8692015490612146565b506007611b8691015442612146565b818102929181159184041417156108f757565b8115612416570490565b634e487b7160e01b600052601260045260246000fd5b60001981018181116108f75761244190611da3565b50916005830154918215612491576001612488611b869561041a94846000526004602052604060002090848060a01b031660005260205260036124886040600020956123b9565b910154906123f9565b50505050600090565b156124a157565b60405162461bcd60e51b815260206004820152602560248201527f446973747269627574696f6e20706572696f6420686173206e6f742079657420604482015264195b99195960da1b6064820152608490fd5b919082018092116108f757565b9060001982018281116108f75761251790611da3565b50600581015492831561249157611b8693612589826125949561258f94600052600460205260406000209060018060a01b031660005260205261257f61256f6125646040600020936123b9565b6003880154906123f9565b9361041a600184015480966123f9565b9454905490612146565b906123f9565b6124f4565b6002549061240c565b9060001982018281116108f7576125b390611da3565b50906005820154156125f657611b8692600052600460205260406000209060018060a01b0316600052602052612589604060002060018101549254905490612146565b505050600090565b6001600160401b0381116107395760051b60200190565b9061261f826125fe565b61262c6040519182611e7d565b828152809261263d601f19916125fe565b019060005b82811061264e57505050565b602090612659612024565b82828501015201612642565b8051821015611d8d5760209160051b010190565b60001981146108f75760010190565b60035460405163b8e86aa560e01b81526001600160a01b0392831660048201529160209183916024918391165afa908115610ae0576000916126c8575090565b90506020813d6020116126ef575b816126e360209383611e7d565b81010312610176575190565b3d91506126d6565b8054600160401b8110156107395761271491600182018155611d75565b819291549060031b91821b91600019901b1916179055565b908060209392818452848401376000828201840152601f01601f1916010190565b6001600160401b03811161073957601f01601f191660200190565b612770611ffe565b506001600160a01b0381169081156127c35761278b81612e9d565b9060ff6127a061279a83612f76565b92612ff2565b92604051946127ae86611e18565b85521660208401526040830152606082015290565b50506040516127d181611e18565b60008152601260208201526040516127e881611e62565b600381526208aa8960eb1b6020820152604082015260405161280981611e62565b6008815267457468657265756d60c01b6020820152606082015290565b6001546001600160a01b0316330361283a57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60026000541461288f576002600055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b600681019081549060009260ff8316612ad957600160ff198094161790556014810191825480612c4f575b50601382019283549081612c18575b5050600554926010830193845414612c0e575b5061271061293860098401546005850154906123f9565b049060018060a01b03806003541691604094855190631dcfcec760e11b808352602060049681858981845afa948515612c04578c95612bd1575b506015840190878254169081156000146129f657505050505050505060035416935491843b156129f2578592916064918551968794859363015f425960e41b8552840152600060248401528160448401525af19081156129e957506129d5575050565b6129df8291611e4f565b6129e65750565b80fd5b513d84823e3d90fd5b8580fd5b8b5163095ea7b360e01b8186019081526001600160a01b039092166024820152604481018c9052979d969c999b959a95999498939793959492938792839290918390612a4f81606481015b03601f198101835282611e7d565b51925af1612a5b612c75565b81612ba1575b5015612b4c57838060035416915492541692813b156129f2578a868094936064938c51978896879563015f425960e41b8752860152602485015260448401525af18015612b425790849291612b2f575b5060035416938786518096819382525afa938415612b25575092612af7575b50508303612adf575b50505050565b60019283820155019182541617905538808080612ad9565b90809250813d8311612b1e575b612b0e8183611e7d565b8101031261017657513880612ad0565b503d612b04565b51903d90823e3d90fd5b612b3b90939193611e4f565b9138612ab1565b86513d85823e3d90fd5b875162461bcd60e51b8152808b01879052602960248201527f455243323048656c706572733a3a73616665417070726f76653a20617070726f6044820152681d994819985a5b195960ba1b6064820152608490fd5b80518015925088908315612bb9575b50505038612a61565b612bc99350820181019101612ca5565b388781612bb0565b9094508181813d8311612bfd575b612be98183611e7d565b81010312612bf957519338612972565b8b80fd5b503d612bdf565b8a513d8e823e3d90fd5b5460055538612921565b54906000198101908111612c3b57612c31601491611da3565b500155388061290e565b634e487b7160e01b86526011600452602486fd5b6013830154906000198101908111612c3b57612c6c601391611da3565b500155386128ff565b3d15612ca0573d90612c868261274d565b91612c946040519384611e7d565b82523d6000602084013e565b606090565b90816020910312610176575180151581036101765790565b60405163a9059cbb60e01b602082019081526001600160a01b03909316602482015260448101939093526000928392908390612cfc8160648101612a41565b51925af1612d08612c75565b81612d6f575b5015612d1657565b60405162461bcd60e51b815260206004820152602b60248201527f455243323048656c706572733a3a736166655472616e736665723a207472616e60448201526a1cd9995c8819985a5b195960aa1b6064820152608490fd5b8051801592508215612d84575b505038612d0e565b612d979250602080918301019101612ca5565b3880612d7c565b6040516323b872dd60e01b602082019081526001600160a01b03938416602483015292909316604484015260648084019490945292825260a0820192906001600160401b03841183851017610739576000809493819460405251925af1612e03612c75565b81612e6e575b5015612e1157565b60405162461bcd60e51b815260206004820152602f60248201527f455243323048656c706572733a3a7472616e7366657246726f6d3a207472616e60448201526e1cd9995c919c9bdb4819985a5b1959608a1b6064820152608490fd5b8051801592508215612e83575b505038612e09565b612e969250602080918301019101612ca5565b3880612e7b565b60405163313ce56760e01b815290602090829060049082906001600160a01b0316614e20fa8091600091612ed8575b5090611b865750601290565b6020813d602011612f10575b81612ef160209383611e7d565b81010312612f0c57519060ff821682036129e6575038612ecc565b5080fd5b3d9150612ee4565b602081830312610176578051906001600160401b038211610176570181601f82011215610176578051612f4a8161274d565b92612f586040519485611e7d565b8184526020828401011161017657611b869160208085019101611af8565b6040516395d89b4160e01b815290600090829060049082906001600160a01b0316614e20fa60009181612fcd575b50611b865750604051612fb681611e62565b60078152662aa725a727aba760c91b602082015290565b612feb9192503d806000833e612fe38183611e7d565b810190612f18565b9038612fa4565b6040516306fdde0360e01b815290600090829060049082906001600160a01b0316614e20fa6000918161304f575b50611b86575060405161303281611e62565b600d81526c2ab735b737bbb7102a37b5b2b760991b602082015290565b6130659192503d806000833e612fe38183611e7d565b903861302056fea2646970667358221220bf7509f300a2abb7d2dba245303ff0941e0fceba7d35548ff4323ab5127325b564736f6c634300081900330000000000000000000000006e16d88ea1dc719987dcf98bca4f2cb8282ce9e8

Deployed Bytecode

0x610200604052600436101561001357600080fd5b60003560e01c8062d5397814611a915780630a1047e314611a735780630f2cba8314611a1b57806312e8e2c31461199c57806326232a2e1461197e5780632d9043b1146119585780632e1a7d4d146117bd578063379607f51461161b5780634487d3df146113e757806353a58de11461138357806361c0a6ec1461135d57806362436c931461133757806364089c4a14611249578063715018a6146111ec5780637c06e82e1461112f5780638c81bc24146111115780638da5cb5b146110e85780638f8f963e14610fc2578063940a4e4514610f72578063aaf5eb6814610f54578063b8e86aa514610f29578063c65c3d9514610f0b578063e2bbb15814610b85578063eff3379514610244578063f2fde38b1461017b5763f5dab7111461013a57600080fd5b346101765760203660031901126101765761017261015e610159611ae2565b612768565b604051918291602083526020830190611b40565b0390f35b600080fd5b3461017657602036600319011261017657610194611ae2565b61019c612826565b6001600160a01b039081169081156101f057600154826bffffffffffffffffffffffff60a01b821617600155167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3005b60405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608490fd5b61010036600319011261017657610259611ae2565b610261611acc565b6084356001600160401b03811161017657610280903690600401611fd1565b91909260a4356001600160401b038111610176576102a2903690600401611fd1565b6001600160401b0360c49692963511610176576102c43660c435600401611fd1565b90929091906001600160a01b03861615610b1e576040516370a0823160e01b81523060048201526020816024816001600160a01b038b165afa908115610ae057600091610aec575b5061032460643530336001600160a01b038b16612d9e565b6040516370a0823160e01b8152306004820152906020826024816001600160a01b038c165afa918215610ae057600092610aaa575b506103679060643592612146565b03610a5957346109dc575b61038060443560643561240c565b156109865760085461271080828103116108f7570360e4351161090d5760065496600160401b88101561073957600188016006556103bd88611da3565b50506001880188116108f7576103d288611da3565b503360005260076020526103ed60018a0160406000206126f7565b600554806108cf575b5060055460138201556001890160055561041f60443561041a6064356002546123f9565b61240c565b600382015560e43560028201556008546009820155606435600b820155600f810180546001600160a01b031916331790556001600160401b0385116107395761046b600e820154611dde565b601f8111610888575b50846000601f821160011461081a5760009161080f575b508560011b906000198760031b1c191617600e8201555b604435600c8201556016810180546001600160a01b038a81166001600160a01b031992831617909255601583018054928a16929091169190911790556001890160108201556001600160401b038211610739576105026012820154611dde565b601f81116107c8575b50816000601f821160011461075a5760009161074f575b508260011b906000198460031b1c19161760128201555b6001600160401b038411610739576105546011820154611dde565b601f81116106f2575b506000601f851160011461064c57936105ef61061396946105fd9460017f9a072e55ca460e89cc4a516d2b7cf4f8d542ac9a825dd702ef1783c8d771fdbc9e958560409f9e9d9c9a600091610641575b50600019600388901b1c191686831b1760118201555b600f828060a01b03910154169c8e519e8f9e8f90610140948594018252602082015201528c019161272c565b9189830360608b015261272c565b91604435608088015286830360a088015261272c565b60643560c085015260e43560e08501526001600160a01b0392831661010085015291166101208301520390a1005b9050870135386105ad565b6011820160005260206000209060005b601f19871681106106da575061061396946105fd9460017f9a072e55ca460e89cc4a516d2b7cf4f8d542ac9a825dd702ef1783c8d771fdbc9e95899560409f9e9d9c9a956105ef96601f198116106106c0575b50508186811b0160118201556105c3565b880135600019600389901b60f8161c1916905538806106af565b90916020600181928f8601358155019301910161065c565b601182016000526020600020601f860160051c810160208710610732575b601f830160051c8201811061072657505061055d565b60008155600101610710565b5080610710565b634e487b7160e01b600052604160045260246000fd5b90508301358b610522565b90506012820160005260206000209060005b601f19851681106107b0575083601f19811610610796575b5050600182811b016012820155610539565b840135600019600385901b60f8161c191690558a80610784565b9091602060018192858901358155019301910161076c565b601282016000526020600020601f840160051c810160208510610808575b601f830160051c820181106107fc57505061050b565b600081556001016107e6565b50806107e6565b90508601358b61048b565b9050600e820160005260206000209060005b601f1988168110610870575086601f19811610610856575b5050600185811b01600e8201556104a2565b870135600019600388901b60f8161c191690558a80610844565b9091602060018192858c01358155019301910161082c565b600e82016000526020600020601f870160051c8101602088106108c8575b601f830160051c820181106108bc575050610474565b600081556001016108a6565b50806108a6565b806000198101116108f7576108e79060001901611da3565b50601460018b019101558a6103f6565b634e487b7160e01b600052601160045260246000fd5b60405162461bcd60e51b815260206004820152604560248201527f50657263656e742072657475726e6564206d757374206265206c65737320746860448201527f616e206f7220657175616c20746f2031303025206d696e757320706c6174666f606482015264726d46656560d81b608482015260a490fd5b60405162461bcd60e51b815260206004820152602860248201527f546f6b656e7320706572207365636f6e64206d75737420626520677265617465604482015267072207468616e20360c41b6064820152608490fd5b60405162461bcd60e51b815260206004820152604960248201527f6d73672e76616c7565206d757374206265207a65726f20666f7220646973747260448201527f69627574696f6e73207468617420646f206e6f74207573652045544820666f72606482015268081d1bdad95b93d55560ba1b608482015260a490fd5b60405162461bcd60e51b815260206004820152602360248201527f496e636f7272656374206e756d626572206f6620746f6b656e732072656365696044820152621d995960ea1b6064820152608490fd5b9091506020813d602011610ad8575b81610ac660209383611e7d565b81010312610176575190610367610359565b3d9150610ab9565b6040513d6000823e3d90fd5b90506020813d602011610b16575b81610b0760209383611e7d565b8101031261017657518961030c565b3d9150610afa565b60643534146103725760405162461bcd60e51b815260206004820152603060248201527f616d6f756e744f555420616e64206d73672e76616c7565206d7573742062652060448201526f65786163746c79207468652073616d6560801b6064820152608490fd5b6040366003190112610176576004356024803590610ba161287e565b6000198301838111610ef657610bb690611da3565b50600a8101805415610eda575b50600d8101544211610e965783600052602091600483526040600020336000528352600160406000200154610e5b5760158201546001600160a01b03919082168015610df25734610d9a5785610c1c9130903390612d9e565b8415610d575760078301908154610c338142612146565b90610d28575b5083546040519160608301908382106001600160401b03831117610d145750604052815260028582019187835260408101926000845289600052600488526040600020336000528852604060002091518255516001820155019051151560ff8019835416911617905560058301610cb18682546124f4565b9055429055600f339201541603610cf9575b6040519283528201527f1599c0fcf897af5babc2bfcf707f5dc050f841b044d97c3251ecec35b9abf80b60403392a26001600055005b3360005260078152610d0f8360406000206126f7565b610cc3565b634e487b7160e01b60009081526041600452fd5b610d48610d3d610d4f926003880154906123f9565b60058701549061240c565b85546124f4565b845587610c39565b83601a6064926040519262461bcd60e51b845260048401528201527f43616e6e6f74206465706f736974207a65726f20746f6b656e730000000000006044820152fd5b60405162461bcd60e51b815260048101869052602b818401527f43616e6e6f742073656e642045544820746f20746f6b656e2d6261736564206460448201526a34b9ba3934b13aba34b7b760a91b6064820152608490fd5b50348514610c1c578360356084926040519262461bcd60e51b845260048401528201527f6465706f73697420616d6f756e7420616e64206d73672e76616c7565206d7573604482015274742062652065786163746c79207468652073616d6560581b6064820152fd5b8260156064926040519262461bcd60e51b845260048401528201527443616e206f6e6c79206465706f736974206f6e636560581b6044820152fd5b60405162461bcd60e51b815260206004820152601d818401527f446973747269627574696f6e20706572696f642068617320656e6465640000006044820152606490fd5b429055610eeb600c820154426124f4565b600d82015584610bc3565b50634e487b7160e01b60009081526011600452fd5b34610176576000366003190112610176576020600654604051908152f35b34610176576020366003190112610176576020610f4c610f47611ae2565b612688565b604051908152f35b34610176576000366003190112610176576020600254604051908152f35b3461017657602036600319011261017657600435610f8e61287e565b60001981019081116108f757610fa6610fbb91611da3565b50610fb6600d820154421161249a565b6128d4565b6001600055005b3461017657610fd036611f43565b600554926000935b801515806110ca575b1561100f5760001981019081116108f757601361100061100992611da3565b50015494612679565b93610fd8565b60009181925b831515806110c1575b1561104d5761102c90612679565b9260001981019081116108f757611044601391611da3565b50015492611015565b9061105782612615565b906000935b801515806110b8575b156110aa576110748282612153565b61107e8685612665565b526110898584612665565b5060001981019081116108f75760136110006110a492611da3565b9361105c565b604051806101728582611f6d565b50838510611065565b5084811061101e565b5060001984018481116108f757836110e1916123f9565b8510610fe1565b34610176576000366003190112610176576001546040516001600160a01b039091168152602090f35b34610176576000366003190112610176576020600554604051908152f35b346101765761113d36611f43565b60065492909160001981019081116108f75782611159916123f9565b918383116111e4575b61116c90836124f4565b828482116111dc575b61117e91612146565b9161118883612615565b9360005b8481106111a157604051806101728882611f6d565b806111c0856111bb6001946111b68888612146565b612146565b612153565b6111ca8289612665565b526111d58188612665565b500161118c565b849150611175565b839250611162565b3461017657600036600319011261017657611205612826565b600180546001600160a01b031981169091556000906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346101765761125736611f43565b9160018060a01b0381169283600052600760209360076020526040600020549060001981019081116108f7578361128d916123f9565b9281841161132d575b6112b4916112a58592836124f4565b90808211611325575b50612146565b936112be85612615565b9560005b8681106112d757604051806101728a82611f6d565b60019082600052848452611309876112fd60406000206112f7858b6124f4565b90611d75565b90549060031b1c612153565b611313828b612665565b5261131e818a612665565b50016112c2565b9050886112ae565b9092508290611296565b34610176576040366003190112610176576020610f4c611355611acc565b60043561259d565b34610176576040366003190112610176576020610f4c61137b611acc565b600435612501565b346101765760403660031901126101765761139c611acc565b600435600052600460205260406000209060018060a01b03166000526020526060604060002080549060ff600260018301549201541690604051928352602083015215156040820152f35b34610176576020366003190112610176576004356006548110156101765761140e90611da3565b506101e081905280546001820154600283015461010052600383015461012052600483015460ff9081166101c05260058401546006850154600786015460088701546009880154600a890154600b8a0154600c8b0154600d8c01546115e39c6115cd9c6115a39b90999298939794969481169392169061149090600e01611e9e565b6101e051600f8101546001600160a01b031660805260108101549d919b91906114bb90601101611e9e565b610180526114ce60126101e05101611e9e565b6101a05260136101e051015460e05260146101e05101546101605260018060a01b0360156101e0510154166101405260018060a01b0360166101e05101541660c05260405160a0526102e09a60a05152602060a051015261010051604060a051015261012051606060a05101526101c0511515608060a051015260a080510152151560c060a051015260e060a0510152151561010060a051015261012060a051015261014060a051015261016060a051015261018060a05101526101a060a0510152806101c060a051015260a0510190611b1b565b906080516101e060a051015261020060a051015260a051810361022060a051015261018051611b1b565b60a051810361024060a05101526101a051611b1b565b60e05161026060a05101526101605161028060a0510152610140516102a060a051015260c0516102c060a051015260a051900360a051f35b346101765760203660031901126101765760043561163761287e565b60001981018181116108f75761164c90611da3565b5061165c600d820154421161249a565b611665816128d4565b816000526004602052604060002033600052602052604060002060028101805460ff81166117865760019060ff19161790556127106116b760016116a93387612501565b9301546002850154906123f9565b6016840154919004926001600160a01b03918390831680611772575060008115611769575b600080809381933390f115610ae0576015905b015416828161175957905060008115611750575b600080809381933390f115610ae0575b604051928352602083015260408201527fd27486cbbd902c694ff070c4b52eb23c8f7828d3688bd3c7293638daec28880860603392a26001600055005b506108fc611703565b611764913390612cbd565b611713565b506108fc6116dc565b60159291611781913390612cbd565b6116ef565b60405162461bcd60e51b815260206004820152600f60248201526e105b1c9958591e4818db185a5b5959608a1b6044820152606490fd5b34610176576020366003190112610176576004356117d961287e565b60001981019081116108f7576117ee90611da3565b50600f8101546001600160a01b0390811633036118f957611814600d830154421161249a565b60088201805460ff81166118b45760ff19166001179055611834826128d4565b60098201546005830154809161184e6127109384926123f9565b0460028501548303928084116108f75761186d611873936015956123f9565b04612146565b92015416806118a3575060008080809381811561189a575b3390f115610ae0576001600055005b506108fc61188b565b906118af913390612cbd565b610fbb565b60405162461bcd60e51b815260206004820152601d60248201527f43726561746f722068617320616c72656164792077697468647261776e0000006044820152606490fd5b60405162461bcd60e51b815260206004820152603160248201527f4f6e6c79207468652063726561746f722063616e2077697468647261772074686044820152706520726563656976656420746f6b656e7360781b6064820152608490fd5b34610176576040366003190112610176576020610f4c611976611acc565b60043561242c565b34610176576000366003190112610176576020600854604051908152f35b34610176576020366003190112610176576004356119b8612826565b6101f481116119c657600855005b60405162461bcd60e51b815260206004820152602760248201527f506c6174666f726d206665652063616e206e6f742062652067726561746572206044820152667468616e20352560c81b6064820152608490fd5b3461017657604036600319011261017657611a34611ae2565b6001600160a01b031660009081526007602052604090208054602435919082101561017657602091611a6591611d75565b90546040519160031b1c8152f35b34610176576020366003190112610176576020610f4c6004356123b9565b3461017657604036600319011261017657610172611ab8611ab0611acc565b600435612153565b604051918291602083526020830190611b89565b602435906001600160a01b038216820361017657565b600435906001600160a01b038216820361017657565b60005b838110611b0b5750506000910152565b8181015183820152602001611afb565b90602091611b3481518092818552858086019101611af8565b601f01601f1916010190565b611b869160018060a01b038251168152602082015160208201526060611b756040840151608060408501526080840190611b1b565b920151906060818403910152611b1b565b90565b9061016080611d6c611d5885516101808652805161018087015260208101516101a087015260408101516101c087015260608101516101e08701526080810151151561020087015260a081015161022087015260c0810151151561024087015260e081015161026087015261010081015115156102808701526101208101516102a08701526101408101516102c0870152611c59848201516102e090818901526101808301516103008901526101a08301516103208901526101c083015190610340890152610460880190611b1b565b6101e08201516001600160a01b0390811661036089015261020083015161038089015261022083015188830361017f199081016103a08b015291926102c092611cbe929091611ca791611b1b565b90610240860151908b8303016103c08c0152611b1b565b926102608101516103e08a01526102808101516104008a0152826102a0820151166104208a015201511661044087015260208701516020870152604087015160408701526060870151151560608701526080870151608087015260a087015160a087015260c087015160c087015260e087015160e08701526101008701511515610100870152610120870151868203610120880152611b40565b610140860151858203610140870152611b40565b93015191015290565b8054821015611d8d5760005260206000200190600090565b634e487b7160e01b600052603260045260246000fd5b600654811015611d8d576017906006600052027ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0190600090565b90600182811c92168015611e0e575b6020831014611df857565b634e487b7160e01b600052602260045260246000fd5b91607f1691611ded565b608081019081106001600160401b0382111761073957604052565b6102e081019081106001600160401b0382111761073957604052565b6001600160401b03811161073957604052565b604081019081106001600160401b0382111761073957604052565b90601f801991011681019081106001600160401b0382111761073957604052565b90604051918260008254611eb181611dde565b90818452602094600191600181169081600014611f215750600114611ee2575b505050611ee092500383611e7d565b565b600090815285812095935091905b818310611f09575050611ee09350820101388080611ed1565b85548884018501529485019487945091830191611ef0565b92505050611ee094925060ff191682840152151560051b820101388080611ed1565b6060906003190112610176576004356001600160a01b038116810361017657906024359060443590565b6020808201906020835283518092526040830192602060408460051b8301019501936000915b848310611fa35750505050505090565b9091929394958480611fc1600193603f198682030187528a51611b89565b9801930193019194939290611f93565b9181601f84011215610176578235916001600160401b038311610176576020838186019501011161017657565b6040519061200b82611e18565b6060808360008152600060208201528160408201520152565b6040519061018082018281106001600160401b0382111761073957806040526101608361205083611e33565b600092838152836101a0830152836101c0830152836101e08301528361020083015283610220830152836102408301528361026083015283610280830152836102a0830152836102c0830152836102e083015283610300830152836103208301526060610340830152836103608301528361038083015260606103a083015260606103c0830152836103e083015283610400830152836104208301528361044083015281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015261212e611ffe565b61012082015261213c611ffe565b6101408201520152565b919082039182116108f757565b9061215c612024565b50811515806123ad575b156123685760001982018281116108f75761218090611da3565b509161218a612024565b9260405161219781611e33565b815481526001820154806020830152600283015460408301526003830154606083015260ff600484015416151590816080840152600584015460a084015260ff600685015416151560c0840152600784015460e084015261230060ff60088601541694610100951515868601526122f66009820154956101209687820152600a8301546101409081830152600b840154610160830152600c840154610180830152600d8401546101a083015261224f600e8501611e9e565b6101c0830152600f8401546001600160a01b039081166101e084015260108501546102008401529761228360118601611e9e565b61022084015261229560128601611e9e565b610240840152601385015461026084015260148501546102808401528860168160158801541696876102a087015201541692836102c08201528d528c6040429101526122e083612768565b908d01526122ed84612768565b908c0152612688565b60a08a0152612688565b60c08801526020870152606086015283168061231e575b5050505090565b60019361234591846000526004602052604060002090600052602052604060002093612501565b608085015260ff600283015416151590840152015460e082015238808080612317565b60405162461bcd60e51b815260206004820152601f60248201527f446973747269627574696f6e204944206973206f7574206f662072616e6765006044820152606490fd5b50600654821115612166565b60001981019081116108f7576123ce90611da3565b50600d810154428110156123ea576007611b8692015490612146565b506007611b8691015442612146565b818102929181159184041417156108f757565b8115612416570490565b634e487b7160e01b600052601260045260246000fd5b60001981018181116108f75761244190611da3565b50916005830154918215612491576001612488611b869561041a94846000526004602052604060002090848060a01b031660005260205260036124886040600020956123b9565b910154906123f9565b50505050600090565b156124a157565b60405162461bcd60e51b815260206004820152602560248201527f446973747269627574696f6e20706572696f6420686173206e6f742079657420604482015264195b99195960da1b6064820152608490fd5b919082018092116108f757565b9060001982018281116108f75761251790611da3565b50600581015492831561249157611b8693612589826125949561258f94600052600460205260406000209060018060a01b031660005260205261257f61256f6125646040600020936123b9565b6003880154906123f9565b9361041a600184015480966123f9565b9454905490612146565b906123f9565b6124f4565b6002549061240c565b9060001982018281116108f7576125b390611da3565b50906005820154156125f657611b8692600052600460205260406000209060018060a01b0316600052602052612589604060002060018101549254905490612146565b505050600090565b6001600160401b0381116107395760051b60200190565b9061261f826125fe565b61262c6040519182611e7d565b828152809261263d601f19916125fe565b019060005b82811061264e57505050565b602090612659612024565b82828501015201612642565b8051821015611d8d5760209160051b010190565b60001981146108f75760010190565b60035460405163b8e86aa560e01b81526001600160a01b0392831660048201529160209183916024918391165afa908115610ae0576000916126c8575090565b90506020813d6020116126ef575b816126e360209383611e7d565b81010312610176575190565b3d91506126d6565b8054600160401b8110156107395761271491600182018155611d75565b819291549060031b91821b91600019901b1916179055565b908060209392818452848401376000828201840152601f01601f1916010190565b6001600160401b03811161073957601f01601f191660200190565b612770611ffe565b506001600160a01b0381169081156127c35761278b81612e9d565b9060ff6127a061279a83612f76565b92612ff2565b92604051946127ae86611e18565b85521660208401526040830152606082015290565b50506040516127d181611e18565b60008152601260208201526040516127e881611e62565b600381526208aa8960eb1b6020820152604082015260405161280981611e62565b6008815267457468657265756d60c01b6020820152606082015290565b6001546001600160a01b0316330361283a57565b606460405162461bcd60e51b815260206004820152602060248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152fd5b60026000541461288f576002600055565b60405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606490fd5b600681019081549060009260ff8316612ad957600160ff198094161790556014810191825480612c4f575b50601382019283549081612c18575b5050600554926010830193845414612c0e575b5061271061293860098401546005850154906123f9565b049060018060a01b03806003541691604094855190631dcfcec760e11b808352602060049681858981845afa948515612c04578c95612bd1575b506015840190878254169081156000146129f657505050505050505060035416935491843b156129f2578592916064918551968794859363015f425960e41b8552840152600060248401528160448401525af19081156129e957506129d5575050565b6129df8291611e4f565b6129e65750565b80fd5b513d84823e3d90fd5b8580fd5b8b5163095ea7b360e01b8186019081526001600160a01b039092166024820152604481018c9052979d969c999b959a95999498939793959492938792839290918390612a4f81606481015b03601f198101835282611e7d565b51925af1612a5b612c75565b81612ba1575b5015612b4c57838060035416915492541692813b156129f2578a868094936064938c51978896879563015f425960e41b8752860152602485015260448401525af18015612b425790849291612b2f575b5060035416938786518096819382525afa938415612b25575092612af7575b50508303612adf575b50505050565b60019283820155019182541617905538808080612ad9565b90809250813d8311612b1e575b612b0e8183611e7d565b8101031261017657513880612ad0565b503d612b04565b51903d90823e3d90fd5b612b3b90939193611e4f565b9138612ab1565b86513d85823e3d90fd5b875162461bcd60e51b8152808b01879052602960248201527f455243323048656c706572733a3a73616665417070726f76653a20617070726f6044820152681d994819985a5b195960ba1b6064820152608490fd5b80518015925088908315612bb9575b50505038612a61565b612bc99350820181019101612ca5565b388781612bb0565b9094508181813d8311612bfd575b612be98183611e7d565b81010312612bf957519338612972565b8b80fd5b503d612bdf565b8a513d8e823e3d90fd5b5460055538612921565b54906000198101908111612c3b57612c31601491611da3565b500155388061290e565b634e487b7160e01b86526011600452602486fd5b6013830154906000198101908111612c3b57612c6c601391611da3565b500155386128ff565b3d15612ca0573d90612c868261274d565b91612c946040519384611e7d565b82523d6000602084013e565b606090565b90816020910312610176575180151581036101765790565b60405163a9059cbb60e01b602082019081526001600160a01b03909316602482015260448101939093526000928392908390612cfc8160648101612a41565b51925af1612d08612c75565b81612d6f575b5015612d1657565b60405162461bcd60e51b815260206004820152602b60248201527f455243323048656c706572733a3a736166655472616e736665723a207472616e60448201526a1cd9995c8819985a5b195960aa1b6064820152608490fd5b8051801592508215612d84575b505038612d0e565b612d979250602080918301019101612ca5565b3880612d7c565b6040516323b872dd60e01b602082019081526001600160a01b03938416602483015292909316604484015260648084019490945292825260a0820192906001600160401b03841183851017610739576000809493819460405251925af1612e03612c75565b81612e6e575b5015612e1157565b60405162461bcd60e51b815260206004820152602f60248201527f455243323048656c706572733a3a7472616e7366657246726f6d3a207472616e60448201526e1cd9995c919c9bdb4819985a5b1959608a1b6064820152608490fd5b8051801592508215612e83575b505038612e09565b612e969250602080918301019101612ca5565b3880612e7b565b60405163313ce56760e01b815290602090829060049082906001600160a01b0316614e20fa8091600091612ed8575b5090611b865750601290565b6020813d602011612f10575b81612ef160209383611e7d565b81010312612f0c57519060ff821682036129e6575038612ecc565b5080fd5b3d9150612ee4565b602081830312610176578051906001600160401b038211610176570181601f82011215610176578051612f4a8161274d565b92612f586040519485611e7d565b8184526020828401011161017657611b869160208085019101611af8565b6040516395d89b4160e01b815290600090829060049082906001600160a01b0316614e20fa60009181612fcd575b50611b865750604051612fb681611e62565b60078152662aa725a727aba760c91b602082015290565b612feb9192503d806000833e612fe38183611e7d565b810190612f18565b9038612fa4565b6040516306fdde0360e01b815290600090829060049082906001600160a01b0316614e20fa6000918161304f575b50611b86575060405161303281611e62565b600d81526c2ab735b737bbb7102a37b5b2b760991b602082015290565b6130659192503d806000833e612fe38183611e7d565b903861302056fea2646970667358221220bf7509f300a2abb7d2dba245303ff0941e0fceba7d35548ff4323ab5127325b564736f6c63430008190033

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

0000000000000000000000006e16d88ea1dc719987dcf98bca4f2cb8282ce9e8

-----Decoded View---------------
Arg [0] : _farm (address): 0x6E16D88Ea1dc719987DCf98bCa4F2cB8282cE9E8

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000006e16d88ea1dc719987dcf98bca4f2cb8282ce9e8


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.