mirror of
https://github.com/Instadapp/fluid-contracts-public.git
synced 2024-07-29 21:57:37 +00:00
373 lines
20 KiB
Solidity
373 lines
20 KiB
Solidity
//SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.21;
|
|
|
|
import "forge-std/Test.sol";
|
|
import "forge-std/console2.sol";
|
|
import "forge-std/StdUtils.sol";
|
|
|
|
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
|
import { Structs } from "../../../../contracts/protocols/lending/merkleDistributor/structs.sol";
|
|
import { Errors } from "../../../../contracts/protocols/lending/merkleDistributor/errors.sol";
|
|
import { Events } from "../../../../contracts/protocols/lending/merkleDistributor/events.sol";
|
|
import { FluidMerkleDistributor } from "../../../../contracts/protocols/lending/merkleDistributor/main.sol";
|
|
|
|
contract FluidMerkleDistributorTest is Test, Events {
|
|
address owner = makeAddr("owner");
|
|
address proposer = makeAddr("proposer");
|
|
address alice = makeAddr("alice");
|
|
|
|
FluidMerkleDistributor distributor;
|
|
|
|
// @dev see source of these test values at the bottom of the file
|
|
bytes32 internal constant TEST_ROOT_1 = 0xb722f4b18110d2040f218f6bdeee9167c957f23490903d7673a04650dbe621dd;
|
|
bytes32 internal constant TEST_CONTENT_HASH_1 = 0xebae91a2dcf9b26375431949c62b80633ac52d0dcd47aa0d7964d431950ba14e; // for test here just a random bytes32
|
|
|
|
bytes32 internal constant TEST_ROOT_2 = 0xdcdc1e16ec7162bbb11074691d5ce88194442e0508d0ef03907c40e825bd709a;
|
|
bytes32 internal constant TEST_CONTENT_HASH_2 = 0xdce87b958009fb6e99231baa505eedcda278bba89d7aaf1c84509901e33c973e; // for test here just a random bytes32
|
|
|
|
bytes32 internal constant TEST_ROOT_3 = 0xbb82a0e2430c67c7f773c9b07f21f091adc4580ee5f9e18e9b73751c99c6f88f;
|
|
bytes32 internal constant TEST_CONTENT_HASH_3 = 0x2411d11e02a26d1abb186dfd0feed4508a1383e182680a5e1b7ddbde46a362db; // for test here just a random bytes32
|
|
|
|
uint40 internal constant DEFAULT_START_BLOCK = 2;
|
|
uint40 internal constant DEFAULT_END_BLOCK = 22;
|
|
|
|
IERC20 internal DISTRIUBTION_TOKEN;
|
|
|
|
function setUp() public virtual {
|
|
vm.createSelectFork(vm.envString("MAINNET_RPC_URL"));
|
|
vm.rollFork(19377005);
|
|
|
|
// constructor params
|
|
// address owner_, address proposer_
|
|
distributor = new FluidMerkleDistributor(owner, proposer);
|
|
|
|
DISTRIUBTION_TOKEN = distributor.TOKEN();
|
|
|
|
// fill with INST tokens from treasury
|
|
vm.prank(0x28849D2b63fA8D361e5fc15cB8aBB13019884d09);
|
|
DISTRIUBTION_TOKEN.transfer(address(distributor), 1e23);
|
|
}
|
|
|
|
function test_deployment() public {
|
|
assertEq(address(distributor.owner()), owner);
|
|
assertEq(distributor.isProposer(proposer), true);
|
|
assertEq(distributor.isProposer(owner), true);
|
|
}
|
|
|
|
function test_proposeRoot() public {
|
|
vm.prank(alice);
|
|
vm.expectRevert(Errors.Unauthorized.selector);
|
|
distributor.proposeRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
|
|
vm.prank(proposer);
|
|
distributor.proposeRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
|
|
assertEq(distributor.hasPendingRoot(), true);
|
|
|
|
Structs.MerkleCycle memory merkleCycle = distributor.pendingMerkleCycle();
|
|
|
|
assertEq(merkleCycle.merkleRoot, TEST_ROOT_1);
|
|
assertEq(merkleCycle.merkleContentHash, TEST_CONTENT_HASH_1);
|
|
assertEq(merkleCycle.cycle, 1);
|
|
assertEq(merkleCycle.startBlock, DEFAULT_START_BLOCK);
|
|
assertEq(merkleCycle.endBlock, DEFAULT_END_BLOCK);
|
|
assertNotEq(merkleCycle.publishBlock, 0);
|
|
assertNotEq(merkleCycle.timestamp, 0);
|
|
}
|
|
|
|
function test_approveRoot() public {
|
|
assertEq(distributor.currentMerkleCycle().merkleRoot, bytes32(""));
|
|
|
|
vm.prank(proposer);
|
|
distributor.proposeRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
|
|
assertEq(distributor.hasPendingRoot(), true);
|
|
|
|
vm.prank(alice);
|
|
vm.expectRevert("UNAUTHORIZED");
|
|
distributor.approveRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
vm.prank(proposer);
|
|
vm.expectRevert("UNAUTHORIZED");
|
|
distributor.approveRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
vm.prank(owner);
|
|
distributor.approveRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
|
|
assertEq(distributor.hasPendingRoot(), false);
|
|
|
|
Structs.MerkleCycle memory merkleCycle = distributor.currentMerkleCycle();
|
|
|
|
assertEq(merkleCycle.merkleRoot, TEST_ROOT_1);
|
|
assertEq(merkleCycle.merkleContentHash, TEST_CONTENT_HASH_1);
|
|
assertEq(merkleCycle.cycle, 1);
|
|
assertEq(merkleCycle.startBlock, DEFAULT_START_BLOCK);
|
|
assertEq(merkleCycle.endBlock, DEFAULT_END_BLOCK);
|
|
assertNotEq(merkleCycle.publishBlock, 0);
|
|
assertNotEq(merkleCycle.timestamp, 0);
|
|
}
|
|
|
|
function test_claim() public {
|
|
vm.prank(proposer);
|
|
distributor.proposeRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
vm.prank(owner);
|
|
distributor.approveRoot(TEST_ROOT_1, TEST_CONTENT_HASH_1, 1, DEFAULT_START_BLOCK, DEFAULT_END_BLOCK);
|
|
|
|
address fToken = 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33;
|
|
address recipient = 0x1111111111111111111111111111111111111111;
|
|
uint256 amount = 5000000000000000000;
|
|
bytes32[] memory proofs = new bytes32[](3);
|
|
proofs[0] = 0x0f2ee3f211cac82f5d789f744f8e05e4ca718acb642dc9493f872e4c0b59f686;
|
|
proofs[1] = 0xa5061119ea1f853333d705665e53dbf5c541ae43f4e4bee83c7b0a429815e1ff;
|
|
proofs[2] = 0x243ffcb2bc8aebe732adc56aca03d46b21765d092adb872cabcc8260cf91b1f0;
|
|
uint256 preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
vm.expectEmit(true, true, true, true);
|
|
emit LogClaimed(0x1111111111111111111111111111111111111111, amount, 1, fToken, block.timestamp, block.number);
|
|
vm.prank(recipient);
|
|
distributor.claim(recipient, amount, fToken, 1, proofs);
|
|
|
|
// claiming again should fail
|
|
vm.expectRevert(Errors.NothingToClaim.selector);
|
|
distributor.claim(recipient, amount, fToken, 1, proofs);
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + amount);
|
|
|
|
// can also claim for another address (no requirement on msg.sender)
|
|
fToken = 0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB;
|
|
recipient = 0x2222222222222222222222222222222222222222;
|
|
amount = 2500000000000000000;
|
|
proofs[0] = 0x1cca30f2fbf18b9e6e696fe49551ab18d1dd61028dc8d64a018aef0eaa1e9d25;
|
|
proofs[1] = 0xa5061119ea1f853333d705665e53dbf5c541ae43f4e4bee83c7b0a429815e1ff;
|
|
proofs[2] = 0x243ffcb2bc8aebe732adc56aca03d46b21765d092adb872cabcc8260cf91b1f0;
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 1, proofs);
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + amount);
|
|
|
|
// add a new cycle
|
|
vm.prank(proposer);
|
|
distributor.proposeRoot(TEST_ROOT_2, TEST_CONTENT_HASH_2, 2, DEFAULT_END_BLOCK + 1, DEFAULT_END_BLOCK + 10);
|
|
vm.prank(owner);
|
|
distributor.approveRoot(TEST_ROOT_2, TEST_CONTENT_HASH_2, 2, DEFAULT_END_BLOCK + 1, DEFAULT_END_BLOCK + 10);
|
|
|
|
// claim new increased amount
|
|
fToken = 0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB;
|
|
recipient = 0x2222222222222222222222222222222222222222;
|
|
amount = 5500000000000000000;
|
|
proofs[0] = 0x889800e6851648e8e54c11ad7bb816c6755b21efe203ece07d260c46a6631237;
|
|
proofs[1] = 0xeda1520064ff7f0c2112900fdac71cd3768db97e03173113a9066c0365b86178;
|
|
proofs[2] = 0x50080647d784950a52dab4a72615591654785fb626599a18842812270f26911e;
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 2, proofs);
|
|
uint256 expectedReceiveAmount = 5500000000000000000 - 2500000000000000000; // already claimed a part previously
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + expectedReceiveAmount);
|
|
|
|
// revert with invalid proof
|
|
fToken = 0x4Ce05f946fe262840496F653817CC1121aE74fac;
|
|
recipient = 0x2222222222222222222222222222222222222223;
|
|
amount = 5500000000000000000;
|
|
proofs = new bytes32[](2);
|
|
|
|
proofs[0] = 0x889800e6851648e8e54c11ad7bb816c6755b21efe203ece07d260c46a6631237;
|
|
proofs[1] = 0x76c8efa363cf15fd80acbf3fbab07c350d0a6c9687a30d364a194fe93e3db568;
|
|
vm.expectRevert(Errors.InvalidProof.selector);
|
|
distributor.claim(recipient, amount, fToken, 2, proofs);
|
|
|
|
// revert with invalid cycle
|
|
proofs[0] = 0x3376bbfa988e4f4680d95a6338a4acc408bc8c429d30429a6d9b2ee01f8f7ef4;
|
|
proofs[1] = 0x76c8efa363cf15fd80acbf3fbab07c350d0a6c9687a30d364a194fe93e3db568;
|
|
vm.expectRevert(Errors.InvalidCycle.selector);
|
|
distributor.claim(recipient, amount, fToken, 3, proofs);
|
|
|
|
// claim full amount at once
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 2, proofs);
|
|
expectedReceiveAmount = 5500000000000000000 - 0; // already claimed a part previously
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + expectedReceiveAmount);
|
|
|
|
// add a new cycle
|
|
vm.prank(proposer);
|
|
distributor.proposeRoot(TEST_ROOT_3, TEST_CONTENT_HASH_3, 3, DEFAULT_END_BLOCK + 11, DEFAULT_END_BLOCK + 20);
|
|
vm.prank(owner);
|
|
distributor.approveRoot(TEST_ROOT_3, TEST_CONTENT_HASH_3, 3, DEFAULT_END_BLOCK + 11, DEFAULT_END_BLOCK + 20);
|
|
|
|
// can claim for multiple fTokens for same user
|
|
recipient = 0x2222222222222222222222222222222222222227;
|
|
amount = 2500000000000000000;
|
|
|
|
fToken = 0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663;
|
|
proofs = new bytes32[](3);
|
|
proofs[0] = 0x78d33aec72ec538b9dc6258b892a509398494928ef66b2411b1c06b4f2b9ed74;
|
|
proofs[1] = 0x496b8a096ce72cb827617fc8c5deb4770cc7fc9afcdaee0fa38f270186790e7b;
|
|
proofs[2] = 0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606;
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 3, proofs);
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + amount);
|
|
|
|
fToken = 0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2;
|
|
proofs[0] = 0x823acb9710b95d5bc5c00a094d672b465957e69637128e597df80760ed7a7c36;
|
|
proofs[1] = 0x496b8a096ce72cb827617fc8c5deb4770cc7fc9afcdaee0fa38f270186790e7b;
|
|
proofs[2] = 0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606;
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 3, proofs);
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + amount);
|
|
|
|
fToken = 0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473;
|
|
proofs[0] = 0x8f24c81628e7da98aecef7815bf25abfa93f4a04d0119ecec52d0cea29cbd1b3;
|
|
proofs[1] = 0x583e11acf71acb893477d92fcd3cffd4f3e52e44d3a82673998998f7a7e8c06f;
|
|
proofs[2] = 0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606;
|
|
preClaimBalance = DISTRIUBTION_TOKEN.balanceOf(recipient);
|
|
distributor.claim(recipient, amount, fToken, 3, proofs);
|
|
assertEq(DISTRIUBTION_TOKEN.balanceOf(recipient), preClaimBalance + amount);
|
|
}
|
|
}
|
|
|
|
// @dev can build a simple merkle root for testing like this in JS:
|
|
// import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
|
|
// const values = [
|
|
// ["0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33", "0x1111111111111111111111111111111111111111", "1", "5000000000000000000"],
|
|
// ["0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB", "0x2222222222222222222222222222222222222222", "1", "2500000000000000000"],
|
|
// ["0x4Ce05f946fe262840496F653817CC1121aE74fac", "0x2222222222222222222222222222222222222223", "1", "2500000000000000000"],
|
|
// ["0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1", "0x2222222222222222222222222222222222222224", "1", "2500000000000000000"],
|
|
// ["0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663", "0x2222222222222222222222222222222222222225", "1", "2500000000000000000"],
|
|
// ["0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2", "0x2222222222222222222222222222222222222226", "1", "2500000000000000000"],
|
|
// ["0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473", "0x2222222222222222222222222222222222222227", "1", "2500000000000000000"],
|
|
// ];
|
|
// const tree = StandardMerkleTree.of(values, ["address", "address", "uint256", "uint256"]);
|
|
// console.log('Merkle Root:', tree.root);
|
|
// let i = 0;
|
|
// for (const value of values) {
|
|
// console.log(`proof for fToken: ${value[0]}:`, tree.getProof(i));
|
|
// i++;
|
|
// }
|
|
//
|
|
// result:
|
|
// Merkle Root:
|
|
// 0xb722f4b18110d2040f218f6bdeee9167c957f23490903d7673a04650dbe621dd
|
|
// proof for fToken: 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33:
|
|
// ['0x0f2ee3f211cac82f5d789f744f8e05e4ca718acb642dc9493f872e4c0b59f686',
|
|
// '0xa5061119ea1f853333d705665e53dbf5c541ae43f4e4bee83c7b0a429815e1ff',
|
|
// '0x243ffcb2bc8aebe732adc56aca03d46b21765d092adb872cabcc8260cf91b1f0'
|
|
// ]
|
|
// proof for fToken: 0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB:
|
|
// ['0x1cca30f2fbf18b9e6e696fe49551ab18d1dd61028dc8d64a018aef0eaa1e9d25',
|
|
// '0xa5061119ea1f853333d705665e53dbf5c541ae43f4e4bee83c7b0a429815e1ff',
|
|
// '0x243ffcb2bc8aebe732adc56aca03d46b21765d092adb872cabcc8260cf91b1f0'
|
|
// ]
|
|
// proof for fToken: 0x4Ce05f946fe262840496F653817CC1121aE74fac:
|
|
// ['0x9dede11f8a1e2592231a5154b525122df8b2c10de49a87dfe1e89878836198c2',
|
|
// '0x901ec68d57ecd635b75c3746297687b8d385a5c232ce5ccd3980e83a44f7fa12',
|
|
// '0xb56477057b0fa0c51bd5096706c8287baac4fa361c62e52f275deafc12af1798'
|
|
// ]
|
|
// proof for fToken: 0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1:
|
|
// ['0x4df43a059b5cfd69765ecf486d7e3cf1c2c9564d44f4681529a3e21995f6816b',
|
|
// '0xad3eab359f1996e5422cb2304001c01c0f7a2d81c3837b91d20e04fffa37d986',
|
|
// '0xb56477057b0fa0c51bd5096706c8287baac4fa361c62e52f275deafc12af1798'
|
|
// ]
|
|
// proof for fToken: 0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663:
|
|
// ['0x58a6cdc6b02b1f0dca8c7bad2a8adedd9ceff23639c69cce9f502f88ee2e449b',
|
|
// '0x901ec68d57ecd635b75c3746297687b8d385a5c232ce5ccd3980e83a44f7fa12',
|
|
// '0xb56477057b0fa0c51bd5096706c8287baac4fa361c62e52f275deafc12af1798'
|
|
// ]
|
|
// proof for fToken: 0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2:
|
|
// ['0x27203de0ca7952b867b011a559d36d62fe8f0a450b19e9df1cf36e23a44212ee',
|
|
// '0xad3eab359f1996e5422cb2304001c01c0f7a2d81c3837b91d20e04fffa37d986',
|
|
// '0xb56477057b0fa0c51bd5096706c8287baac4fa361c62e52f275deafc12af1798'
|
|
// ]
|
|
// proof for fToken: 0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473:
|
|
// ['0x9b650ec44a3d61d8b32a8562c7c881b15bf48759afea0750e19fc037b6344af9',
|
|
// '0x243ffcb2bc8aebe732adc56aca03d46b21765d092adb872cabcc8260cf91b1f0'
|
|
// ]
|
|
//
|
|
// cycle 2 with increased amounts:
|
|
// const values = [
|
|
// ["0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33", "0x1111111111111111111111111111111111111111", "2", "8000000000000000000"],
|
|
// ["0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB", "0x2222222222222222222222222222222222222222", "2", "5500000000000000000"],
|
|
// ["0x4Ce05f946fe262840496F653817CC1121aE74fac", "0x2222222222222222222222222222222222222223", "2", "5500000000000000000"],
|
|
// ["0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1", "0x2222222222222222222222222222222222222224", "2", "5500000000000000000"],
|
|
// ["0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663", "0x2222222222222222222222222222222222222225", "2", "5500000000000000000"],
|
|
// ["0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2", "0x2222222222222222222222222222222222222226", "2", "5500000000000000000"],
|
|
// ["0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473", "0x2222222222222222222222222222222222222227", "2", "5500000000000000000"],
|
|
// ];
|
|
// result:
|
|
// Merkle Root:
|
|
// 0xdcdc1e16ec7162bbb11074691d5ce88194442e0508d0ef03907c40e825bd709a
|
|
// proof for fToken: 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33:
|
|
// ['0x64d8da7a48f9ddb12c076505241a70ff6dc005a22f44686e0f9a37ec2f30f96a',
|
|
// '0xeda1520064ff7f0c2112900fdac71cd3768db97e03173113a9066c0365b86178',
|
|
// '0x50080647d784950a52dab4a72615591654785fb626599a18842812270f26911e'
|
|
// ]
|
|
// proof for fToken: 0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB:
|
|
// ['0x889800e6851648e8e54c11ad7bb816c6755b21efe203ece07d260c46a6631237',
|
|
// '0xeda1520064ff7f0c2112900fdac71cd3768db97e03173113a9066c0365b86178',
|
|
// '0x50080647d784950a52dab4a72615591654785fb626599a18842812270f26911e'
|
|
// ]
|
|
// proof for fToken: 0x4Ce05f946fe262840496F653817CC1121aE74fac:
|
|
// ['0x3376bbfa988e4f4680d95a6338a4acc408bc8c429d30429a6d9b2ee01f8f7ef4',
|
|
// '0x76c8efa363cf15fd80acbf3fbab07c350d0a6c9687a30d364a194fe93e3db568'
|
|
// ]
|
|
// proof for fToken: 0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1:
|
|
// ['0xa17a97d025b966174c986da52d002fcf6883d3e5163ed64e87440505f5fdc83e',
|
|
// '0x8f0af5ef2d41f7fb76d621fefa1bb0f8445ff21a15522aded243cf56425c922b',
|
|
// '0x50080647d784950a52dab4a72615591654785fb626599a18842812270f26911e'
|
|
// ]
|
|
// proof for fToken: 0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663:
|
|
// ['0xce209d1402e1df9c7033fde9bbdda6c58dba2e9364273eb5ca0af90ec9e60cb4',
|
|
// '0x8f0af5ef2d41f7fb76d621fefa1bb0f8445ff21a15522aded243cf56425c922b',
|
|
// '0x50080647d784950a52dab4a72615591654785fb626599a18842812270f26911e'
|
|
// ]
|
|
// proof for fToken: 0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2:
|
|
// ['0x3a30d50e77d241bf449a4ff2c81c28754b6c184b11dce3187bfd92b3060f77c0',
|
|
// '0xdef3b6b82257e3fe53768aed76d66b3a670c63f7420051c2c8e0a8407b332f58',
|
|
// '0x76c8efa363cf15fd80acbf3fbab07c350d0a6c9687a30d364a194fe93e3db568'
|
|
// ]
|
|
// proof for fToken: 0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473:
|
|
// ['0x489c8ad1341484f7008d69b1280b4e4572c925736290464111224c9890008b31',
|
|
// '0xdef3b6b82257e3fe53768aed76d66b3a670c63f7420051c2c8e0a8407b332f58',
|
|
// '0x76c8efa363cf15fd80acbf3fbab07c350d0a6c9687a30d364a194fe93e3db568'
|
|
// ]
|
|
//
|
|
// cycle 3 with same user for different fTokens:
|
|
// const values = [
|
|
// ["0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33", "0x1111111111111111111111111111111111111111", "3", "5000000000000000000"],
|
|
// ["0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB", "0x2222222222222222222222222222222222222222", "3", "2500000000000000000"],
|
|
// ["0x4Ce05f946fe262840496F653817CC1121aE74fac", "0x2222222222222222222222222222222222222223", "3", "2500000000000000000"],
|
|
// ["0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1", "0x2222222222222222222222222222222222222224", "3", "2500000000000000000"],
|
|
// ["0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663", "0x2222222222222222222222222222222222222227", "3", "2500000000000000000"],
|
|
// ["0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2", "0x2222222222222222222222222222222222222227", "3", "2500000000000000000"],
|
|
// ["0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473", "0x2222222222222222222222222222222222222227", "3", "2500000000000000000"],
|
|
// ];
|
|
// result:
|
|
// Merkle Root:
|
|
// 0xbb82a0e2430c67c7f773c9b07f21f091adc4580ee5f9e18e9b73751c99c6f88f
|
|
// proof for fToken: 0x9Fb7b4477576Fe5B32be4C1843aFB1e55F251B33:
|
|
// ['0x9cfa912e27eb4661e288a20061c10b4c4549df52b9c294dd6f7e2b43bfc5a9b9',
|
|
// '0x583e11acf71acb893477d92fcd3cffd4f3e52e44d3a82673998998f7a7e8c06f',
|
|
// '0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606'
|
|
// ]
|
|
// proof for fToken: 0x0b5d53972927D4B0f103eea55e19fCfEE025A9AB:
|
|
// ['0x08e5de7b7226389886e976fb4f8c552c355b8c80129ed74f0385deb2ef2131d9',
|
|
// '0xcc1123387b54e08e95ab389fb991310fe2ce6d832999473a0a61262e927889a8',
|
|
// '0x7dba5063b48257d6ba141a372b2f3dce88e525d58bac3bdae6e9015195ae183d'
|
|
// ]
|
|
// proof for fToken: 0x4Ce05f946fe262840496F653817CC1121aE74fac:
|
|
// ['0x62f2ef4b532602a6dc17e7fd2e24321dd64cfebed90632cdeb454e4aeb2ea7de',
|
|
// '0x7dba5063b48257d6ba141a372b2f3dce88e525d58bac3bdae6e9015195ae183d'
|
|
// ]
|
|
// proof for fToken: 0x4FA61f7e0f30b8004C8e471F01b2e8e644f6b8C1:
|
|
// ['0x65dbe725b043aedb3bc1921fadd4273bd765d06e5726a5d498615f16a972c6c3',
|
|
// '0xcc1123387b54e08e95ab389fb991310fe2ce6d832999473a0a61262e927889a8',
|
|
// '0x7dba5063b48257d6ba141a372b2f3dce88e525d58bac3bdae6e9015195ae183d'
|
|
// ]
|
|
// proof for fToken: 0xFDa9fe8e90f99F9eb5a6CCddA11708ceB10Ba663:
|
|
// ['0x78d33aec72ec538b9dc6258b892a509398494928ef66b2411b1c06b4f2b9ed74',
|
|
// '0x496b8a096ce72cb827617fc8c5deb4770cc7fc9afcdaee0fa38f270186790e7b',
|
|
// '0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606'
|
|
// ]
|
|
// proof for fToken: 0x04D44fD629Be46E2f5f7962F6A8420c16d22d4e2:
|
|
// ['0x823acb9710b95d5bc5c00a094d672b465957e69637128e597df80760ed7a7c36',
|
|
// '0x496b8a096ce72cb827617fc8c5deb4770cc7fc9afcdaee0fa38f270186790e7b',
|
|
// '0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606'
|
|
// ]
|
|
// proof for fToken: 0xD8Afe4D67Eb2fC91Ce472AA3a3A1618D8A938473:
|
|
// ['0x8f24c81628e7da98aecef7815bf25abfa93f4a04d0119ecec52d0cea29cbd1b3',
|
|
// '0x583e11acf71acb893477d92fcd3cffd4f3e52e44d3a82673998998f7a7e8c06f',
|
|
// '0x458904ee917a00c8f950ff287f87653caef1acd1d7d7bec0a72f5c727e0e4606'
|
|
// ]
|