|
| 1 | +methods { |
| 2 | + function getMarketId(MorphoHarness.Market) external returns MorphoHarness.Id envfree; |
| 3 | + function getVirtualTotalSupply(MorphoHarness.Id) external returns uint256 envfree; |
| 4 | + function getVirtualTotalSupplyShares(MorphoHarness.Id) external returns uint256 envfree; |
| 5 | + function MathLib.mulDivDown(uint256 a, uint256 b, uint256 c) internal returns uint256 => summaryMulDivDown(a,b,c); |
| 6 | + function MathLib.mulDivUp(uint256 a, uint256 b, uint256 c) internal returns uint256 => summaryMulDivUp(a,b,c); |
| 7 | + function SafeTransferLib.safeTransfer(address token, address to, uint256 value) internal => NONDET; |
| 8 | + function SafeTransferLib.safeTransferFrom(address token, address from, address to, uint256 value) internal => NONDET; |
| 9 | + function _.onMorphoSupply(uint256 assets, bytes data) external => HAVOC_ECF; |
| 10 | +} |
| 11 | + |
| 12 | +function summaryMulDivUp(uint256 x, uint256 y, uint256 d) returns uint256 { |
| 13 | + return require_uint256((x * y + (d - 1)) / d); |
| 14 | +} |
| 15 | + |
| 16 | +function summaryMulDivDown(uint256 x, uint256 y, uint256 d) returns uint256 { |
| 17 | + return require_uint256((x * y) / d); |
| 18 | +} |
| 19 | + |
| 20 | +/* There should be no profit from supply followed immediately by withdraw */ |
| 21 | +rule supplyWithdraw() { |
| 22 | + MorphoHarness.Market market; |
| 23 | + uint256 assets; |
| 24 | + uint256 shares; |
| 25 | + uint256 suppliedAssets; |
| 26 | + uint256 withdrawnAssets; |
| 27 | + uint256 suppliedShares; |
| 28 | + uint256 withdrawnShares; |
| 29 | + address onbehalf; |
| 30 | + address receiver; |
| 31 | + bytes data; |
| 32 | + env e1; |
| 33 | + env e2; |
| 34 | + |
| 35 | + require e1.block.timestamp == e2.block.timestamp; |
| 36 | + |
| 37 | + suppliedAssets, suppliedShares = supply(e1, market, assets, shares, onbehalf, data); |
| 38 | + |
| 39 | + MorphoHarness.Id id = getMarketId(market); |
| 40 | + assert suppliedAssets * (getVirtualTotalSupplyShares(id) - suppliedShares) >= suppliedShares * (getVirtualTotalSupply(id) - suppliedAssets); |
| 41 | + assert suppliedAssets * getVirtualTotalSupplyShares(id) >= suppliedShares * getVirtualTotalSupply(id); |
| 42 | + |
| 43 | + withdrawnAssets, withdrawnShares = withdraw(e2, market, 0, suppliedShares, onbehalf, receiver); |
| 44 | + |
| 45 | + assert withdrawnShares == suppliedShares; |
| 46 | + assert withdrawnAssets <= suppliedAssets; |
| 47 | +} |
| 48 | + |
| 49 | +/* There should be no profit from withdraw followed immediately by supply */ |
| 50 | +rule withdrawSupply() { |
| 51 | + MorphoHarness.Market market; |
| 52 | + uint256 assets; |
| 53 | + uint256 shares; |
| 54 | + uint256 suppliedAssets; |
| 55 | + uint256 withdrawnAssets; |
| 56 | + uint256 suppliedShares; |
| 57 | + uint256 withdrawnShares; |
| 58 | + address onbehalf; |
| 59 | + address receiver; |
| 60 | + bytes data; |
| 61 | + env e1; |
| 62 | + env e2; |
| 63 | + |
| 64 | + require e1.block.timestamp == e2.block.timestamp; |
| 65 | + |
| 66 | + withdrawnAssets, withdrawnShares = withdraw(e2, market, assets, shares, onbehalf, receiver); |
| 67 | + |
| 68 | + MorphoHarness.Id id = getMarketId(market); |
| 69 | + assert withdrawnAssets * (getVirtualTotalSupplyShares(id) + withdrawnShares) <= withdrawnShares * (getVirtualTotalSupply(id) + withdrawnAssets); |
| 70 | + assert withdrawnAssets * getVirtualTotalSupplyShares(id) <= withdrawnShares * getVirtualTotalSupply(id); |
| 71 | + |
| 72 | + suppliedAssets, suppliedShares = supply(e1, market, withdrawnAssets, 0, onbehalf, data); |
| 73 | + |
| 74 | + assert suppliedAssets == withdrawnAssets && withdrawnShares >= suppliedShares; |
| 75 | +} |
0 commit comments