-
-
Notifications
You must be signed in to change notification settings - Fork 111
/
Copy pathLilFractional.t.sol
146 lines (104 loc) · 4.49 KB
/
LilFractional.t.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.10;
import { Vm } from 'forge-std/Vm.sol';
import { DSTest } from 'ds-test/test.sol';
import { stdError } from 'forge-std/stdlib.sol';
import { ERC721 } from 'solmate/tokens/ERC721.sol';
import { LilFractional, NFTShare } from '../LilFractional.sol';
contract User {}
contract TestNFT is ERC721('Test NFT', 'TEST') {
uint256 public tokenId = 1;
function tokenURI(uint256) public pure override returns (string memory) {
return 'test';
}
function mint() public returns (uint256) {
_mint(msg.sender, tokenId);
return tokenId++;
}
}
contract LilFractionalTest is DSTest {
uint256 nftId;
User internal user;
TestNFT internal nft;
Vm internal hevm = Vm(HEVM_ADDRESS);
LilFractional internal lilFractional;
event VaultCreated(LilFractional.Vault vault);
event VaultDestroyed(LilFractional.Vault vault);
event Transfer(address indexed from, address indexed to, uint256 amount);
function setUp() public {
user = new User();
nft = new TestNFT();
lilFractional = new LilFractional();
// Ensure contract can access tokens
nft.setApprovalForAll(address(lilFractional), true);
// Ensure contract can access user's tokens
hevm.prank(address(user));
nft.setApprovalForAll(address(lilFractional), true);
nftId = nft.mint();
}
function testCanSplitToken() public {
assertEq(nft.ownerOf(nftId), address(this));
hevm.expectEmit(true, true, false, true);
emit Transfer(address(0), address(this), 100 ether);
uint256 vaultId = lilFractional.split(nft, nftId, 100 ether, 'Fractionalised NFT', 'FRAC');
(
ERC721 nftContract,
uint256 tokenId,
uint256 supply,
NFTShare tokenContract
) = lilFractional.getVault(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(address(nftContract), address(nft));
assertEq(tokenId, nftId);
assertEq(supply, 100 ether);
assertEq(tokenContract.balanceOf(address(this)), 100 ether);
}
function testNonOwnerCannotSplitToken() public {
assertEq(nft.ownerOf(nftId), address(this));
hevm.prank(address(user));
hevm.expectRevert('WRONG_FROM'); // error comes from ERC721 impl. (solmate in this test)
lilFractional.split(nft, nftId, 100 ether, 'Fractionalised NFT', 'FRAC');
assertEq(nft.ownerOf(nftId), address(this));
}
function testTotalSupplyOwnerCanJoinToken() public {
uint256 vaultId = lilFractional.split(nft, nftId, 100 ether, 'Fractionalised NFT', 'FRAC');
(, , , NFTShare tokenContract) = lilFractional.getVault(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(tokenContract.balanceOf(address(this)), 100 ether);
tokenContract.approve(address(lilFractional), type(uint256).max);
lilFractional.join(vaultId);
assertEq(nft.ownerOf(nftId), address(this));
assertEq(tokenContract.balanceOf(address(this)), 0);
(, uint256 tokenId, , ) = lilFractional.getVault(vaultId);
assertEq(tokenId, 0);
}
function testCannotJoinNonExistingToken() public {
hevm.expectRevert(abi.encodeWithSignature('VaultNotFound()'));
lilFractional.join(1);
}
function testPartialHolderCannotJoinToken() public {
uint256 vaultId = lilFractional.split(nft, nftId, 100 ether, 'Fractionalised NFT', 'FRAC');
(, , , NFTShare tokenContract) = lilFractional.getVault(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(tokenContract.balanceOf(address(this)), 100 ether);
tokenContract.transfer(address(user), 100 ether - 1);
hevm.startPrank(address(user));
tokenContract.approve(address(lilFractional), type(uint256).max);
hevm.expectRevert(stdError.arithmeticError); // error might vary depending on the ERC20 impl. (this one comes from solmate)
lilFractional.join(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(tokenContract.balanceOf(address(user)), 100 ether - 1);
}
function testNonHolderCannotJoinToken() public {
uint256 vaultId = lilFractional.split(nft, nftId, 100 ether, 'Fractionalised NFT', 'FRAC');
(, , , NFTShare tokenContract) = lilFractional.getVault(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(tokenContract.balanceOf(address(this)), 100 ether);
hevm.startPrank(address(user));
tokenContract.approve(address(lilFractional), type(uint256).max);
hevm.expectRevert(stdError.arithmeticError); // error might vary depending on the ERC20 impl. (this one comes from solmate)
lilFractional.join(vaultId);
assertEq(nft.ownerOf(nftId), address(lilFractional));
assertEq(tokenContract.balanceOf(address(this)), 100 ether);
}
}