forked from crytic/properties
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSenderIndependentProps.sol
105 lines (89 loc) · 4.02 KB
/
SenderIndependentProps.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
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.0;
import {CryticERC4626PropertyBase} from "../util/ERC4626PropertyTestBase.sol";
contract CryticERC4626SenderIndependent is CryticERC4626PropertyBase {
// todo: these properties may have issues in vaults that have super weird redemption curves.
// If that happens, use a proxy contract to compare results instead of msg.sender's state
/// @notice verify `maxDeposit()` assumes the receiver/sender has infinite assets
function verify_maxDepositIgnoresSenderAssets(uint256 tokens) public {
address receiver = address(this);
uint256 maxDepositBefore = vault.maxDeposit(receiver);
asset.mint(receiver, tokens);
uint256 maxDepositAfter = vault.maxDeposit(receiver);
assertEq(
maxDepositBefore,
maxDepositAfter,
"maxDeposit must assume the agent has infinite assets"
);
}
/// @notice verify `maxMint()` assumes the receiver/sender has infinite assets
function verify_maxMintIgnoresSenderAssets(uint256 tokens) public {
address receiver = address(this);
uint256 maxMintBefore = vault.maxMint(receiver);
asset.mint(receiver, tokens);
uint256 maxMintAfter = vault.maxMint(receiver);
assertEq(
maxMintBefore,
maxMintAfter,
"maxMint must assume the agent has infinite assets"
);
}
/// @notice verify `previewMint()` does not account for msg.sender asset balance
function verify_previewMintIgnoresSender(
uint256 tokens,
uint256 shares
) public {
address receiver = address(this);
uint256 assetsExpectedBefore = vault.previewMint(shares);
prepareAddressForDeposit(receiver, tokens);
uint256 assetsExpectedAfter = vault.previewMint(shares);
assertEq(
assetsExpectedBefore,
assetsExpectedAfter,
"previewMint must not be dependent on msg.sender"
);
}
/// @notice verify `previewDeposit()` does not account for msg.sender asset balance
function verify_previewDepositIgnoresSender(uint256 tokens) public {
address receiver = address(this);
uint256 sharesExpectedBefore = vault.previewDeposit(tokens);
prepareAddressForDeposit(receiver, tokens);
uint256 sharesExpectedAfter = vault.previewDeposit(tokens);
assertEq(
sharesExpectedBefore,
sharesExpectedAfter,
"previewDeposit must not be dependent on msg.sender"
);
}
/// @notice verify `previewWithdraw()` does not account for msg.sender asset balance
function verify_previewWithdrawIgnoresSender(uint256 tokens) public {
address receiver = address(this);
uint256 sharesExpectedBefore = vault.previewWithdraw(tokens);
prepareAddressForDeposit(receiver, tokens);
vault.deposit(tokens, receiver);
uint256 sharesExpectedAfter = vault.previewWithdraw(tokens);
assertEq(
sharesExpectedBefore,
sharesExpectedAfter,
"previewWithdraw must not be dependent on msg.sender"
);
// keep this property relatively stateless
vault.redeem(vault.balanceOf(receiver), receiver, receiver);
}
/// @notice verify `previewRedeem()` does not account for msg.sender asset balance
function verify_previewRedeemIgnoresSender(uint256 shares) public {
address receiver = address(this);
uint256 tokensExpectedBefore = vault.previewRedeem(shares);
uint256 assetsToDeposit = vault.previewMint(shares);
prepareAddressForDeposit(receiver, assetsToDeposit);
vault.deposit(assetsToDeposit, receiver);
uint256 tokensExpectedAfter = vault.previewRedeem(shares);
assertEq(
tokensExpectedBefore,
tokensExpectedAfter,
"previewRedeem must not be dependent on msg.sender"
);
// keep this property relatively stateless
vault.redeem(vault.balanceOf(receiver), receiver, receiver);
}
}