mirror of
https://github.com/Instadapp/fluid-contracts-public.git
synced 2024-07-29 21:57:37 +00:00
d7a58e88ff
ARB: deploy protocols
542 lines
21 KiB
Solidity
542 lines
21 KiB
Solidity
//SPDX-License-Identifier: MIT
|
|
pragma solidity 0.8.21;
|
|
|
|
import "forge-std/Test.sol";
|
|
import "forge-std/console.sol";
|
|
|
|
import { LiquidityBaseTest } from "../../liquidity/liquidityBaseTest.t.sol";
|
|
import { IFluidLiquidityLogic } from "../../../../contracts/liquidity/interfaces/iLiquidity.sol";
|
|
import { FluidVaultT1 } from "../../../../contracts/protocols/vault/vaultT1/coreModule/main.sol";
|
|
import { FluidVaultT1Secondary } from "../../../../contracts/protocols/vault/vaultT1/coreModule/main2.sol";
|
|
import { FluidVaultT1Admin } from "../../../../contracts/protocols/vault/vaultT1/adminModule/main.sol";
|
|
import { MockOracle } from "../../../../contracts/mocks/mockOracle.sol";
|
|
import { FluidVaultFactory } from "../../../../contracts/protocols/vault/factory/main.sol";
|
|
import { FluidVaultT1DeploymentLogic } from "../../../../contracts/protocols/vault/factory/deploymentLogics/vaultT1Logic.sol";
|
|
import { MockonERC721Received } from "../../../../contracts/mocks/mockERC721.sol";
|
|
import { FluidVaultResolver } from "../../../../contracts/periphery/resolvers/vault/main.sol";
|
|
import { FluidLiquidityResolver } from "../../../../contracts/periphery/resolvers/liquidity/main.sol";
|
|
import { IFluidLiquidity } from "../../../../contracts/liquidity/interfaces/iLiquidity.sol";
|
|
|
|
import "../../testERC20.sol";
|
|
import "../../testERC20Dec6.sol";
|
|
import "../../../../contracts/protocols/lending/lendingRewardsRateModel/main.sol";
|
|
|
|
abstract contract VaultFactoryBaseTest is LiquidityBaseTest {
|
|
using stdStorage for StdStorage;
|
|
|
|
FluidVaultFactory vaultFactory;
|
|
FluidVaultT1DeploymentLogic vaultT1Deployer;
|
|
address vaultAdminImplementation_;
|
|
address vaultSecondaryImplementation_;
|
|
|
|
FluidLiquidityResolver liquidityResolver;
|
|
FluidVaultResolver vaultResolver;
|
|
|
|
function setUp() public virtual override {
|
|
super.setUp();
|
|
|
|
vaultFactory = new FluidVaultFactory(admin);
|
|
vm.prank(admin);
|
|
vaultFactory.setDeployer(alice, true);
|
|
vaultAdminImplementation_ = address(new FluidVaultT1Admin());
|
|
vaultSecondaryImplementation_ = address(new FluidVaultT1Secondary());
|
|
vaultT1Deployer = new FluidVaultT1DeploymentLogic(
|
|
address(liquidity),
|
|
vaultAdminImplementation_,
|
|
vaultSecondaryImplementation_
|
|
);
|
|
|
|
vm.prank(admin);
|
|
vaultFactory.setGlobalAuth(alice, true);
|
|
vm.prank(admin);
|
|
vaultFactory.setVaultDeploymentLogic(address(vaultT1Deployer), true);
|
|
|
|
liquidityResolver = new FluidLiquidityResolver(IFluidLiquidity(address(liquidity)));
|
|
vaultResolver = new FluidVaultResolver(address(vaultFactory), address(liquidity), address(liquidityResolver));
|
|
}
|
|
|
|
function _deployVault(uint64 nonce) internal returns (uint256) {
|
|
vm.setNonceUnsafe(address(vaultFactory), nonce);
|
|
stdstore.target(address(vaultFactory)).sig("totalVaults()").checked_write(nonce - 1);
|
|
vm.startPrank(alice);
|
|
nonce = vm.getNonce(address(vaultFactory));
|
|
bytes memory vaultT1CreationCode = abi.encodeCall(vaultT1Deployer.vaultT1, (address(USDC), address(DAI)));
|
|
address vault = vaultFactory.deployVault(address(vaultT1Deployer), vaultT1CreationCode);
|
|
uint256 vaultId = FluidVaultT1(vault).VAULT_ID();
|
|
address computedVaultAddress = vaultFactory.getVaultAddress(vaultId);
|
|
vm.stopPrank();
|
|
// console.log("Computed Vault Address for vaultId '%s' with nonce '%s': ", vaultId, nonce, computedVaultAddress);
|
|
assertEq(vault, computedVaultAddress);
|
|
return vaultId;
|
|
}
|
|
|
|
struct ERC721Data {
|
|
address owner;
|
|
uint256 id;
|
|
uint256 positionIndex;
|
|
uint256 vaultId;
|
|
}
|
|
|
|
function calculateStorageSlotUintMapping(uint256 slot_, uint key_) internal pure returns (bytes32) {
|
|
return keccak256(abi.encode(key_, slot_));
|
|
}
|
|
|
|
function calculateDoubleAddressUintMapping(
|
|
uint256 slot_,
|
|
address key1_,
|
|
uint key2_
|
|
) internal pure returns (bytes32) {
|
|
bytes32 intermediateSlot_ = keccak256(abi.encode(key1_, slot_));
|
|
return keccak256(abi.encode(key2_, intermediateSlot_));
|
|
}
|
|
|
|
function _getERC721BalanceOf(address owner) internal returns (uint256) {
|
|
return (vaultFactory.readFromStorage(calculateDoubleAddressUintMapping(4, owner, 0))) & type(uint32).max;
|
|
}
|
|
|
|
function _getERC721VaultId(uint256 id) internal returns (uint256) {
|
|
return (vaultFactory.readFromStorage(calculateStorageSlotUintMapping(3, id)) >> 192) & type(uint32).max;
|
|
}
|
|
|
|
function _getERC721PositionIndex(uint256 id) internal returns (uint256) {
|
|
return (vaultFactory.readFromStorage(calculateStorageSlotUintMapping(3, id)) >> 160) & type(uint32).max;
|
|
}
|
|
|
|
function _getERC721TokenIndex(address owner, uint256 i) internal returns (uint256) {
|
|
uint256 index = i + 1;
|
|
uint256 word = index / 8;
|
|
uint256 bitIndex = (index % 8) * 32;
|
|
uint256 temp = (vaultFactory.readFromStorage(calculateDoubleAddressUintMapping(4, owner, word)));
|
|
return (temp >> bitIndex) & type(uint32).max;
|
|
}
|
|
|
|
function _getERC721DataOfOwner(address owner) internal returns (ERC721Data[] memory datas) {
|
|
uint256 balance = _getERC721BalanceOf(owner);
|
|
|
|
datas = new ERC721Data[](balance);
|
|
|
|
for (uint256 i = 0; i < balance; i++) {
|
|
uint256 id = _getERC721TokenIndex(owner, i);
|
|
uint256 vaultId = _getERC721VaultId(id);
|
|
uint256 positionIndex = _getERC721PositionIndex(id);
|
|
datas[i] = ERC721Data({
|
|
id: id,
|
|
owner: vaultFactory.ownerOf(id),
|
|
vaultId: vaultId,
|
|
positionIndex: positionIndex
|
|
});
|
|
}
|
|
|
|
return datas;
|
|
}
|
|
|
|
function _mintERC721ForOwnerWithVaultId(address owner, uint256 vaultId) internal returns (uint256) {
|
|
address computedVaultAddress = vaultFactory.getVaultAddress(vaultId);
|
|
vm.prank(computedVaultAddress);
|
|
return vaultFactory.mint(vaultId, owner);
|
|
}
|
|
|
|
function _validateTotalSupply() internal {
|
|
uint256 totalSupply = vaultFactory.totalSupply();
|
|
|
|
for (uint i = 0; i < totalSupply; i++) {
|
|
assertEq(vaultFactory.tokenByIndex(i), i + 1, "Validate: totalSupply");
|
|
}
|
|
}
|
|
|
|
function _validateOwnerByIndex(address owner) internal {
|
|
uint256 balanceOf = vaultFactory.balanceOf(owner);
|
|
assertEq(_getERC721BalanceOf(owner), balanceOf);
|
|
for (uint i = 0; i < balanceOf; i++) {
|
|
uint256 id = vaultFactory.tokenOfOwnerByIndex(owner, i);
|
|
assertNotEq(id, 0, "Validate: OwnerByIndex");
|
|
assertEq(id, _getERC721TokenIndex(owner, i), "Validate: OwnerByIndex by low level");
|
|
}
|
|
assertEq(_getERC721TokenIndex(owner, balanceOf), 0);
|
|
}
|
|
|
|
function _validate(address fromOwner, address toOwner) internal {
|
|
_validateTotalSupply();
|
|
_validateOwnerByIndex(fromOwner);
|
|
_validateOwnerByIndex(toOwner);
|
|
}
|
|
|
|
function _transferAndValidate(uint256 id, address from, address to) internal {
|
|
ERC721Data[] memory beforeFromERC721Datas = _getERC721DataOfOwner(from);
|
|
ERC721Data[] memory beforeToERC721Datas = _getERC721DataOfOwner(to);
|
|
|
|
uint256 positionIndex = _getERC721PositionIndex(id);
|
|
assertNotEq(positionIndex, 0, "Validate: Position Index of ERC721 to transfer if not 0");
|
|
uint256 vaultId = _getERC721VaultId(id);
|
|
assertNotEq(vaultId, 0);
|
|
|
|
_validate(from, to);
|
|
|
|
vm.prank(from);
|
|
vaultFactory.transferFrom(from, to, id);
|
|
|
|
_validate(from, to);
|
|
|
|
ERC721Data[] memory afterToERC721Datas = _getERC721DataOfOwner(to);
|
|
|
|
for (uint256 i = 0; i < beforeFromERC721Datas.length; i++) {
|
|
uint256 checkERC721Id = beforeFromERC721Datas[i].id;
|
|
address checkERC721Owner = vaultFactory.ownerOf(checkERC721Id);
|
|
uint256 checkERC721PositionIndex = _getERC721PositionIndex(checkERC721Id);
|
|
assertEq(
|
|
beforeFromERC721Datas[i].vaultId,
|
|
_getERC721VaultId(checkERC721Id),
|
|
"Loop: Validate vaultId for 'from'"
|
|
);
|
|
if (i + 1 < positionIndex) {
|
|
assertEq(checkERC721Owner, from, "Loop: Validate checkERC721Owner < for 'from'");
|
|
assertEq(
|
|
beforeFromERC721Datas[i].positionIndex,
|
|
checkERC721PositionIndex,
|
|
"Loop: Validate positionIndex < for 'from'"
|
|
);
|
|
} else if (i + 1 == positionIndex) {
|
|
assertEq(beforeFromERC721Datas[i].id, checkERC721Id, "Loop: Validate NFT ID == for 'from'");
|
|
assertEq(checkERC721Owner, to, "Loop: Validate checkERC721Owner == for 'from'");
|
|
} else if (i + 1 == beforeFromERC721Datas.length) {
|
|
assertEq(checkERC721Owner, from, "Loop: Validate checkERC721Owner +1 for 'from'");
|
|
assertEq(positionIndex, checkERC721PositionIndex, "Loop: Validate positionIndex +1 for 'from'");
|
|
} else {
|
|
assertEq(checkERC721Owner, from);
|
|
assertEq(
|
|
beforeFromERC721Datas[i].positionIndex,
|
|
checkERC721PositionIndex,
|
|
"Loop: Validate positionIndex > for 'from'"
|
|
);
|
|
}
|
|
}
|
|
|
|
for (uint256 i = 0; i < beforeToERC721Datas.length; i++) {
|
|
assertEq(beforeToERC721Datas[i].id, afterToERC721Datas[i].id, "Loop: validate NftID of 'to'");
|
|
assertEq(beforeToERC721Datas[i].vaultId, afterToERC721Datas[i].vaultId, "Loop: validate vaultId of 'to'");
|
|
assertEq(beforeToERC721Datas[i].owner, afterToERC721Datas[i].owner, "Loop: validate owner of 'to'");
|
|
assertEq(
|
|
beforeToERC721Datas[i].positionIndex,
|
|
afterToERC721Datas[i].positionIndex,
|
|
"Loop: validate position of 'to'"
|
|
);
|
|
}
|
|
assertEq(
|
|
(beforeToERC721Datas.length > 0 ? beforeToERC721Datas[beforeToERC721Datas.length - 1].positionIndex : 0) +
|
|
1,
|
|
afterToERC721Datas[beforeToERC721Datas.length].positionIndex,
|
|
"Validate Last PositionIndex of 'to'"
|
|
);
|
|
assertEq(vaultId, afterToERC721Datas[beforeToERC721Datas.length].vaultId, "Validate Last VaultId of 'to'");
|
|
}
|
|
|
|
uint256[] aliceERC721TransferData;
|
|
uint256[] bobERC721TransferData;
|
|
|
|
function _ERC721SimulateTransfer(uint256 nftToTransferPosition) internal {
|
|
uint32[3] memory nonces = [uint32(1), 2, 3];
|
|
uint256[] memory vaultIds = new uint256[](nonces.length);
|
|
|
|
for (uint256 i = 0; i < nonces.length; i++) {
|
|
vaultIds[i] = _deployVault(uint64(nonces[i]));
|
|
}
|
|
|
|
uint256 aliceNFTId;
|
|
for (uint256 i = 0; i < aliceERC721TransferData.length; i++) {
|
|
if (i == nftToTransferPosition - 1) {
|
|
aliceNFTId = _mintERC721ForOwnerWithVaultId(address(alice), aliceERC721TransferData[i]);
|
|
} else {
|
|
_mintERC721ForOwnerWithVaultId(address(alice), aliceERC721TransferData[i]);
|
|
}
|
|
}
|
|
assertEq(vaultFactory.balanceOf(alice), aliceERC721TransferData.length);
|
|
|
|
for (uint256 i = 0; i < bobERC721TransferData.length; i++) {
|
|
_mintERC721ForOwnerWithVaultId(address(bob), bobERC721TransferData[i]);
|
|
}
|
|
assertEq(vaultFactory.balanceOf(bob), bobERC721TransferData.length);
|
|
|
|
_transferAndValidate(aliceNFTId, alice, bob);
|
|
assertEq(vaultFactory.balanceOf(alice), aliceERC721TransferData.length - 1);
|
|
assertEq(vaultFactory.balanceOf(bob), bobERC721TransferData.length + 1);
|
|
}
|
|
}
|
|
|
|
contract VaultFactoryTest is VaultFactoryBaseTest {
|
|
function testDeployNewVault() public {
|
|
MockOracle oracle = new MockOracle();
|
|
|
|
FluidVaultT1Admin vaultWithAdmin_;
|
|
|
|
vm.prank(alice);
|
|
|
|
bytes memory vaultT1CreationCode = abi.encodeCall(vaultT1Deployer.vaultT1, (address(USDC), address(DAI)));
|
|
|
|
address vault = vaultFactory.deployVault(address(vaultT1Deployer), vaultT1CreationCode);
|
|
|
|
// Updating admin related things to setup vault
|
|
vaultWithAdmin_ = FluidVaultT1Admin(address(vault));
|
|
vm.prank(alice);
|
|
vaultWithAdmin_.updateCoreSettings(
|
|
10000, // supplyFactor_ => 100%
|
|
10000, // borrowFactor_ => 100%
|
|
8000, // collateralFactor_ => 80%
|
|
9000, // liquidationThreshold_ => 90%
|
|
9500, // liquidationMaxLimit_ => 95%
|
|
500, // withdrawGap_ => 5%
|
|
100, // liquidationPenalty_ => 1%
|
|
100 // borrowFee_ => 1%
|
|
);
|
|
vm.prank(alice);
|
|
vaultWithAdmin_.updateOracle(address(oracle));
|
|
vm.prank(alice);
|
|
vaultWithAdmin_.updateRebalancer(address(admin));
|
|
|
|
// console.log("Vault Address", vault);
|
|
assertNotEq(vault, address(0));
|
|
|
|
uint256 vaultId = FluidVaultT1(vault).VAULT_ID();
|
|
// console.log("Vault Id", vaultId);
|
|
|
|
address computedVaultAddress = vaultFactory.getVaultAddress(vaultId);
|
|
// console.log("Computed Vault Address", computedVaultAddress);
|
|
assertEq(vault, computedVaultAddress);
|
|
}
|
|
|
|
/////////// Bob no NFTs ///////
|
|
function testTransferOfNFTAliceOneToBobZero() public {
|
|
aliceERC721TransferData = [1];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenLastToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(7);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightLastToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(8);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenRandomToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightRandomToBobZero() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = new uint256[](0);
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
/////////// Bob no NFTs ///////
|
|
|
|
/////////// Bob 1 NFTs ///////
|
|
function testTransferOfNFTAliceOneToBobOne() public {
|
|
aliceERC721TransferData = [1];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenLastToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(7);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightLastToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(8);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenRandomToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightRandomToBobOne() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
/////////// Bob 1 NFTs ///////
|
|
|
|
/////////// Bob 7 NFTs ///////
|
|
|
|
function testTransferOfNFTAliceOneToBobSeven() public {
|
|
aliceERC721TransferData = [1];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenLastToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(7);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightLastToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(8);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenRandomToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightRandomToBobSeven() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
/////////// Bob 7 NFTs ///////
|
|
/////////// Bob 8 NFTs ///////
|
|
|
|
function testTransferOfNFTAliceOneToBobEight() public {
|
|
aliceERC721TransferData = [1];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(1);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenLastToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(7);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightLastToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(8);
|
|
}
|
|
|
|
function testTransferOfNFTAliceSevenRandomToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
function testTransferOfNFTAliceEightRandomToBobEight() public {
|
|
aliceERC721TransferData = [1, 2, 3, 1, 3, 2, 2, 3];
|
|
bobERC721TransferData = [2, 2, 3, 1, 1, 3, 1, 3];
|
|
_ERC721SimulateTransfer(3);
|
|
}
|
|
|
|
// /////////// Bob 8 NFTs ///////
|
|
|
|
function testDoubleTransfer() public {
|
|
address mockFactoryContract = address(new MockonERC721Received());
|
|
|
|
uint32[3] memory nonces = [uint32(1), 2, 3];
|
|
uint256[] memory vaultIds = new uint256[](nonces.length);
|
|
|
|
for (uint256 i = 0; i < nonces.length; i++) {
|
|
vaultIds[i] = _deployVault(uint64(nonces[i]));
|
|
}
|
|
|
|
_mintERC721ForOwnerWithVaultId(address(alice), 1);
|
|
uint256 aliceNFTId = _mintERC721ForOwnerWithVaultId(address(alice), 3);
|
|
_mintERC721ForOwnerWithVaultId(address(alice), 2);
|
|
_mintERC721ForOwnerWithVaultId(address(alice), 3);
|
|
|
|
assertEq(_getERC721PositionIndex(aliceNFTId), 2);
|
|
vm.prank(alice);
|
|
vaultFactory.safeTransferFrom(alice, mockFactoryContract, aliceNFTId, abi.encode(alice));
|
|
|
|
assertEq(vaultFactory.balanceOf(alice), 4);
|
|
assertEq(vaultFactory.balanceOf(mockFactoryContract), 0);
|
|
assertEq(vaultFactory.totalSupply(), 4);
|
|
assertEq(_getERC721PositionIndex(aliceNFTId), 4);
|
|
}
|
|
|
|
function testComputeAddress() public {
|
|
// nonce of deployment starts with 1.
|
|
uint32[20] memory nonces = [
|
|
1,
|
|
2,
|
|
3,
|
|
10,
|
|
126,
|
|
127,
|
|
128,
|
|
129,
|
|
254,
|
|
255,
|
|
256,
|
|
257,
|
|
65534,
|
|
65535,
|
|
65536,
|
|
65537,
|
|
16777214,
|
|
16777215,
|
|
16777216,
|
|
16777217
|
|
];
|
|
|
|
for (uint256 i = 0; i < nonces.length; i++) {
|
|
_deployVault(uint64(nonces[i]));
|
|
}
|
|
}
|
|
}
|