diff --git a/test/invariant/EthMultiVaultBasicInvariant.t.sol b/test/invariant/EthMultiVaultBasicInvariant.t.sol index a717a6d9..c79e70ec 100644 --- a/test/invariant/EthMultiVaultBasicInvariant.t.sol +++ b/test/invariant/EthMultiVaultBasicInvariant.t.sol @@ -24,10 +24,13 @@ contract EthMultiVaultBasicInvariantTest is InvariantEthMultiVaultBase { targetContract(address(actor)); // selectors for actor functions - bytes4[] memory selectors = new bytes4[](3); + bytes4[] memory selectors = new bytes4[](6); selectors[0] = actor.createAtom.selector; // createAtom selectors[1] = actor.depositAtom.selector; // depositAtom selectors[2] = actor.redeemAtom.selector; // redeemAtom + selectors[3] = actor.createTriple.selector; // createTriple + selectors[4] = actor.depositTriple.selector; // depositTriple + selectors[5] = actor.redeemTriple.selector; // redeemTriple FuzzSelector memory fuzzSelector = FuzzSelector({addr: address(actor), selectors: selectors}); @@ -39,11 +42,15 @@ contract EthMultiVaultBasicInvariantTest is InvariantEthMultiVaultBase { // assets less than or equal to eth balance invariant_ethMultiVault_asset_solvency(); // shares less than or equal to assets - //invariant_ethMultiVault_share_solvency(); + invariant_ethMultiVault_share_solvency(); + emit log_named_uint("actor.numberOfCalls()---", actor.numberOfCalls()); emit log_named_uint("actor.numberOfAtoms()---", actor.numberOfAtoms()); - emit log_named_uint("actor.numberOfDeposits()", actor.numberOfDeposits()); - emit log_named_uint("actor.numberOfRedeems()-", actor.numberOfRedeems()); + emit log_named_uint("actor.numberOfAtomDeposits()", actor.numberOfAtomDeposits()); + emit log_named_uint("actor.numberOfAtomRedeems()-", actor.numberOfAtomRedeems()); + emit log_named_uint("actor.numberOfTriples()---", actor.numberOfTriples()); + emit log_named_uint("actor.numberOfTripleDeposits()", actor.numberOfTripleDeposits()); + emit log_named_uint("actor.numberOfTripleRedeems()", actor.numberOfTripleRedeems()); emit log_named_uint("ETHMULTIVAULT ETH BALANCE---", address(ethMultiVault).balance); } } diff --git a/test/invariant/EthMultiVaultSingleVaultInvariant.t.sol b/test/invariant/EthMultiVaultSingleVaultInvariant.t.sol index 443f7b14..24e47e09 100644 --- a/test/invariant/EthMultiVaultSingleVaultInvariant.t.sol +++ b/test/invariant/EthMultiVaultSingleVaultInvariant.t.sol @@ -20,6 +20,13 @@ contract EthMultiVaultSingleVaultInvariantTest is InvariantEthMultiVaultBase { // create single vault ethMultiVault.createAtom{value: 100 ether}("PEPE"); + // create 2 more atoms for the triple vault + ethMultiVault.createAtom{value: 100 ether}("WIF"); + ethMultiVault.createAtom{value: 100 ether}("BASE"); + + // create triple vault + ethMultiVault.createTriple{value: 100 ether}(1, 2, 3); + // deploy actor actor = new EthMultiVaultSingleVaultActor(ethMultiVault); @@ -27,9 +34,11 @@ contract EthMultiVaultSingleVaultInvariantTest is InvariantEthMultiVaultBase { targetContract(address(actor)); // selectors for actor functions - bytes4[] memory selectors = new bytes4[](2); + bytes4[] memory selectors = new bytes4[](4); selectors[0] = actor.depositAtom.selector; // depositAtom selectors[1] = actor.redeemAtom.selector; // redeemAtom + selectors[2] = actor.depositTriple.selector; // depositTriple + selectors[3] = actor.redeemTriple.selector; // redeemTriple FuzzSelector memory fuzzSelector = FuzzSelector({addr: address(actor), selectors: selectors}); @@ -40,9 +49,14 @@ contract EthMultiVaultSingleVaultInvariantTest is InvariantEthMultiVaultBase { function invariant_ethMultiVault_single() external { // assets less than or equal to eth balance invariant_ethMultiVault_asset_solvency(); + // shares less than or equal to assets + invariant_ethMultiVault_share_solvency(); + emit log_named_uint("actor.numberOfCalls()---", actor.numberOfCalls()); - emit log_named_uint("actor.numberOfDeposits()", actor.numberOfDeposits()); - emit log_named_uint("actor.numberOfRedeems()-", actor.numberOfRedeems()); + emit log_named_uint("actor.numberOfAtomDeposits()", actor.numberOfAtomDeposits()); + emit log_named_uint("actor.numberOfAtomRedeems()-", actor.numberOfAtomRedeems()); + emit log_named_uint("actor.numberOfTripleDeposits()", actor.numberOfTripleDeposits()); + emit log_named_uint("actor.numberOfTripleRedeems()", actor.numberOfTripleRedeems()); emit log_named_uint("EthMultiVAULT ETH BALANCE---", address(ethMultiVault).balance); } } diff --git a/test/invariant/InvariantEthMultiVaultBase.sol b/test/invariant/InvariantEthMultiVaultBase.sol index fbdebe72..2f0ff270 100644 --- a/test/invariant/InvariantEthMultiVaultBase.sol +++ b/test/invariant/InvariantEthMultiVaultBase.sol @@ -18,6 +18,18 @@ contract InvariantEthMultiVaultBase is EthMultiVaultBase { for (uint256 i = 1; i <= ethMultiVault.count(); i++) { totalAssetsAcrossAllVaults += super.vaultTotalAssets(i); } + + uint256 totalAssetsAcrossAllCounterTripleVaults; + uint256 counterTripleId = type(uint256).max - 1; + for (uint256 i = 1; i <= ethMultiVault.count(); i++) { + if (ethMultiVault.isTripleId(i)) { + totalAssetsAcrossAllCounterTripleVaults += super.vaultTotalAssets(counterTripleId); + counterTripleId--; + } + } + + totalAssetsAcrossAllVaults += totalAssetsAcrossAllCounterTripleVaults; + assertLe(totalAssetsAcrossAllVaults, address(ethMultiVault).balance); } @@ -25,5 +37,13 @@ contract InvariantEthMultiVaultBase is EthMultiVaultBase { for (uint256 i = 1; i <= ethMultiVault.count(); i++) { assertLe(super.vaultTotalShares(i), super.vaultTotalAssets(i)); } + + uint256 counterTripleId = type(uint256).max; + for (uint256 i = 1; i <= ethMultiVault.count(); i++) { + if (ethMultiVault.isTripleId(i)) { + assertLe(super.vaultTotalShares(counterTripleId), super.vaultTotalAssets(counterTripleId)); + counterTripleId--; + } + } } } diff --git a/test/invariant/actors/EthMultiVaultActor.sol b/test/invariant/actors/EthMultiVaultActor.sol index 1a18d52c..c1cd983c 100644 --- a/test/invariant/actors/EthMultiVaultActor.sol +++ b/test/invariant/actors/EthMultiVaultActor.sol @@ -18,8 +18,11 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { // ghost variables uint256 public numberOfCalls; uint256 public numberOfAtoms; - uint256 public numberOfDeposits; - uint256 public numberOfRedeems; + uint256 public numberOfAtomDeposits; + uint256 public numberOfAtomRedeems; + uint256 public numberOfTriples; + uint256 public numberOfTripleDeposits; + uint256 public numberOfTripleRedeems; modifier useActor(uint256 actorIndexSeed) { currentActor = actors[bound(actorIndexSeed, 0, actors.length - 1)]; @@ -35,9 +38,11 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { actorPks.push(i + 1); actors.push(vm.addr(actorPks[i])); } - //actors.push(msg.sender); + actors.push(msg.sender); } + receive() external payable {} + function getVaultTotalAssets(uint256 vaultId) public view returns (uint256 totalAssets) { (totalAssets,) = actEthMultiVault.vaults(vaultId); } @@ -57,7 +62,7 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { return calculatedAssetsForReceiver + protocolFees + exitFees; } - function createAtom(bytes calldata _data, uint256 msgValue, uint256 actorIndexSeed) + function createAtom(bytes calldata data, uint256 msgValue, uint256 actorIndexSeed) public useActor(actorIndexSeed) returns (uint256) @@ -94,7 +99,7 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; // create atom - uint256 id = actEthMultiVault.createAtom{value: msgValue}(_data); + uint256 id = actEthMultiVault.createAtom{value: msgValue}(data); assertEq(id, actEthMultiVault.count()); checkDepositOnAtomVaultCreation(id, msgValue, totalAssetsBefore, totalSharesBefore); @@ -117,72 +122,72 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { } function depositAtom( - address _receiver, - uint256 _vaultId, + address receiver, + uint256 vaultId, uint256 msgValue, - bytes calldata _data, + bytes calldata data, uint256 actorIndexSeed ) public useActor(actorIndexSeed) returns (uint256) { numberOfCalls++; - numberOfDeposits++; + numberOfAtomDeposits++; emit log_named_uint( "==================================== ACTOR depositAtom ====================================", 6000000009 ); emit log_named_address("currentActor-----", currentActor); emit log_named_uint("currentActor.balance", currentActor.balance); emit log_named_uint("msgValue------------", msgValue); - // bound _receiver to msg.sender always - _receiver = currentActor; + // bound receiver to msg.sender always + receiver = currentActor; uint256 shares; // if no atom exist yet, create and deposit on one if (actEthMultiVault.count() == 0) { vm.deal(currentActor, getAtomCost()); - _vaultId = actEthMultiVault.createAtom{value: getAtomCost()}(_data); - emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(_vaultId, currentActor)); + vaultId = actEthMultiVault.createAtom{value: getAtomCost()}(data); + emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); msgValue = bound(msgValue, getMinDeposit(), 10 ether); vm.deal(currentActor, msgValue); emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 1|||||||||||||||||||||||||||||||||||", 1); - uint256 totalAssetsBefore = vaultTotalAssets(_vaultId); - uint256 totalSharesBefore = vaultTotalShares(_vaultId); + uint256 totalAssetsBefore = vaultTotalAssets(vaultId); + uint256 totalSharesBefore = vaultTotalShares(vaultId); uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; - shares = actEthMultiVault.depositAtom{value: msgValue}(_receiver, _vaultId); + shares = actEthMultiVault.depositAtom{value: msgValue}(receiver, vaultId); checkDepositIntoVault( - msgValue - getProtocolFeeAmount(msgValue, _vaultId), _vaultId, totalAssetsBefore, totalSharesBefore + msgValue - getProtocolFeeAmount(msgValue, vaultId), vaultId, totalAssetsBefore, totalSharesBefore ); - checkProtocolVaultBalance(_vaultId, msgValue, protocolVaultBalanceBefore); + checkProtocolVaultBalance(vaultId, msgValue, protocolVaultBalanceBefore); } else { // deposit on existing vault - // bound _vaultId between 1 and count() - if (_vaultId == 0 || _vaultId > actEthMultiVault.count()) { - _vaultId = bound(_vaultId, 1, actEthMultiVault.count()); + // bound vaultId between 1 and count() + if (vaultId == 0 || vaultId > actEthMultiVault.count()) { + vaultId = bound(vaultId, 1, actEthMultiVault.count()); } - emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); // bound msgValue to between minDeposit and 10 ether msgValue = bound(msgValue, getAtomCost(), 10 ether); vm.deal(currentActor, msgValue); emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 2|||||||||||||||||||||||||||||||||||", 2); - uint256 totalAssetsBefore = vaultTotalAssets(_vaultId); - uint256 totalSharesBefore = vaultTotalShares(_vaultId); + uint256 totalAssetsBefore = vaultTotalAssets(vaultId); + uint256 totalSharesBefore = vaultTotalShares(vaultId); uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; - shares = actEthMultiVault.depositAtom{value: msgValue}(_receiver, _vaultId); + shares = actEthMultiVault.depositAtom{value: msgValue}(receiver, vaultId); checkDepositIntoVault( - msgValue - getProtocolFeeAmount(msgValue, _vaultId), _vaultId, totalAssetsBefore, totalSharesBefore + msgValue - getProtocolFeeAmount(msgValue, vaultId), vaultId, totalAssetsBefore, totalSharesBefore ); - checkProtocolVaultBalance(_vaultId, msgValue, protocolVaultBalanceBefore); + checkProtocolVaultBalance(vaultId, msgValue, protocolVaultBalanceBefore); } // deposit atom emit log_named_uint("balance currentActor", currentActor.balance); @@ -192,9 +197,9 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { emit log_named_uint( "------------------------------------ POST STATE -------------------------------------------", 6000000009 ); - emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultTAssets--------", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets--------", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); emit log_named_uint( "==================================== ACTOR depositAtom ====================================", shares ); @@ -202,15 +207,15 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { } function redeemAtom( - uint256 _shares2Redeem, - address _receiver, - uint256 _vaultId, + uint256 shares2Redeem, + address receiver, + uint256 vaultId, uint256 msgValue, - bytes calldata _data, + bytes calldata data, uint256 actorIndexSeed ) public useActor(actorIndexSeed) returns (uint256) { numberOfCalls++; - numberOfRedeems++; + numberOfAtomRedeems++; emit log_named_uint( "==================================== ACTOR redeemAtom START ====================================", 6000000009 @@ -221,65 +226,65 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { // if no atom vaults exist create one and deposit on it if (actEthMultiVault.count() == 0) { vm.deal(currentActor, getAtomCost()); - _vaultId = actEthMultiVault.createAtom{value: getAtomCost()}(_data); + vaultId = actEthMultiVault.createAtom{value: getAtomCost()}(data); msgValue = bound(msgValue, getMinDeposit(), 10 ether); vm.deal(currentActor, msgValue); emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 1|||||||||||||||||||||||||||||||||||", 1); - _shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, 1); + shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, 1); } else { // vault exists - // bound _vaultId between 1 and count() - if (_vaultId == 0 || _vaultId > actEthMultiVault.count()) { - _vaultId = bound(_vaultId, 1, actEthMultiVault.count()); + // bound vaultId between 1 and count() + if (vaultId == 0 || vaultId > actEthMultiVault.count()) { + vaultId = bound(vaultId, 1, actEthMultiVault.count()); } // if vault balance of the selected vault is 0, deposit minDeposit - if (getVaultBalanceForAddress(_vaultId, currentActor) == 0) { + if (getVaultBalanceForAddress(vaultId, currentActor) == 0) { vm.deal(currentActor, 10 ether); - emit log_named_uint("vaultTShares--", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultTAssets--", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultBalanceOf", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets--", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf", getVaultBalanceForAddress(vaultId, currentActor)); msgValue = bound(msgValue, getAtomCost(), 10 ether); - emit log_named_uint("REEEE getVaultTotalAssets(_vaultId)", getVaultTotalAssets(_vaultId)); - emit log_named_uint("REEEE getVaultTotalShares(_vaultId)", getVaultTotalShares(_vaultId)); + emit log_named_uint("REEEE getVaultTotalAssets(vaultId)", getVaultTotalAssets(vaultId)); + emit log_named_uint("REEEE getVaultTotalShares(vaultId)", getVaultTotalShares(vaultId)); emit log_named_uint("|||||||||||||||||||||||||||||||BRANCH 2||||||||||||||||||||||||||||||||||||", 2); - _shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, _vaultId); - emit log_named_uint("_shares2Redeem", _shares2Redeem); + shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, vaultId); + emit log_named_uint("shares2Redeem", shares2Redeem); } else { emit log_named_uint("|||||||||||||||||||||||||||||||BRANCH 3||||||||||||||||||||||||||||||||||||", 3); - // bound _shares2Redeem to between 1 and vaultBalanceOf - _shares2Redeem = bound(_shares2Redeem, 1, getVaultBalanceForAddress(_vaultId, currentActor)); - emit log_named_uint("_shares2Redeem", _shares2Redeem); + // bound shares2Redeem to between 1 and vaultBalanceOf + shares2Redeem = bound(shares2Redeem, 1, getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint("shares2Redeem", shares2Redeem); } } // use the redeemer as the receiver always - _receiver = currentActor; + receiver = currentActor; - emit log_named_uint("before vaultTotalShares--", getVaultTotalAssets(_vaultId)); - emit log_named_uint("before vaultTAssets------", getVaultTotalShares(_vaultId)); - emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("before vaultTotalShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("before vaultTAssets------", getVaultTotalShares(vaultId)); + emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); // snapshots before redeem uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; - uint256 userSharesBeforeRedeem = getSharesInVault(_vaultId, _receiver); - uint256 userBalanceBeforeRedeem = address(_receiver).balance; + uint256 userSharesBeforeRedeem = getSharesInVault(vaultId, receiver); + uint256 userBalanceBeforeRedeem = address(receiver).balance; - uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, _vaultId); + uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, vaultId); // redeem atom - uint256 assetsForReceiver = actEthMultiVault.redeemAtom(_shares2Redeem, _receiver, _vaultId); + uint256 assetsForReceiver = actEthMultiVault.redeemAtom(shares2Redeem, receiver, vaultId); - checkProtocolVaultBalance(_vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); + checkProtocolVaultBalance(vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); - assertEq(getSharesInVault(_vaultId, _receiver), userSharesBeforeRedeem - _shares2Redeem); - assertEq(address(_receiver).balance - userBalanceBeforeRedeem, assetsForReceiver); + assertEq(getSharesInVault(vaultId, receiver), userSharesBeforeRedeem - shares2Redeem); + assertEq(address(receiver).balance - userBalanceBeforeRedeem, assetsForReceiver); // logs emit log_named_uint( "------------------------------------ POST STATE -------------------------------------------", 6000000009 ); - emit log_named_uint("vaultTotalShares--", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultTAssets------", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTotalShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets------", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); emit log_named_uint( "==================================== ACTOR redeemAtom END ====================================", assetsForReceiver @@ -287,5 +292,325 @@ contract EthMultiVaultActor is Test, EthMultiVaultHelpers { return assetsForReceiver; } - receive() external payable {} + function createTriple( + uint256 subjectId, + uint256 predicateId, + uint256 objectId, + uint256 msgValue, + uint256 actorIndexSeed + ) public useActor(actorIndexSeed) returns (uint256) { + numberOfCalls++; + numberOfTriples++; + emit log_named_uint( + "==================================== ACTOR createTriple START ====================================", + 6000000009 + ); + emit log_named_address("currentActor-----", currentActor); + emit log_named_uint("currentActor.balance", currentActor.balance); + emit log_named_uint("msgValue------------", msgValue); + if (currentActor.balance < getTripleCost()) { + vm.deal(currentActor, 1 ether); + } + if (msgValue < getTripleCost()) { + msgValue = getTripleCost(); + } + if (msgValue > currentActor.balance) { + if (msgValue > 1 ether) { + vm.deal(currentActor, 1 ether); + msgValue = 1 ether; + } else { + vm.deal(currentActor, msgValue); + } + } + emit log_named_uint("msg.sender.balance Right before create", currentActor.balance); + emit log_named_address("msg.sender-----", currentActor); + + uint256 vaultId = _createTripleChecks(msgValue, subjectId, predicateId, objectId); + + // logs + emit log_named_uint( + "------------------------------------ POST STATE ------------------------------------------", 6000000009 + ); + emit log_named_uint("msg.sender.balance", currentActor.balance); + emit log_named_uint("vaultTotalShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets------", getVaultTotalShares(vaultId)); + emit log_named_uint( + "==================================== ACTOR createTriple END ====================================", vaultId + ); + return vaultId; + } + + function depositTriple(address receiver, uint256 vaultId, uint256 msgValue, uint256 actorIndexSeed) + public + useActor(actorIndexSeed) + returns (uint256) + { + numberOfCalls++; + numberOfTripleDeposits++; + emit log_named_uint( + "==================================== ACTOR depositTriple ====================================", 6000000009 + ); + emit log_named_address("currentActor-----", currentActor); + emit log_named_uint("currentActor.balance", currentActor.balance); + emit log_named_uint("msgValue------------", msgValue); + // bound receiver to msg.sender always + receiver = currentActor; + uint256 shares; + // if no triple exist yet, create and deposit on one + if (actEthMultiVault.count() == 0) { + vm.deal(currentActor, getTripleCost()); + vaultId = actEthMultiVault.createTriple{value: getTripleCost()}(1, 2, 3); + emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + msgValue = bound(msgValue, getMinDeposit(), 10 ether); + vm.deal(currentActor, msgValue); + emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 1|||||||||||||||||||||||||||||||||||", 1); + + _createTripleChecks(msgValue, 1, 2, 3); + } else { + // vault exists + if (vaultId == 0 || vaultId > actEthMultiVault.count()) { + uint256[] memory tripleVaults = new uint256[](actEthMultiVault.count()); + uint256 tripleVaultsCount = 0; + for (uint256 i = 1; i <= actEthMultiVault.count(); i++) { + if (actEthMultiVault.isTripleId(i)) { + tripleVaults[tripleVaultsCount] = i; + tripleVaultsCount++; + } + } + + vaultId = tripleVaults[bound(actorIndexSeed, 0, tripleVaultsCount - 1)]; + } + + emit log_named_uint("vaultTotalAssets----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + // bound msgValue to between minDeposit and 10 ether + msgValue = bound(msgValue, getTripleCost(), 10 ether); + vm.deal(currentActor, msgValue); + emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 2|||||||||||||||||||||||||||||||||||", 2); + + shares = _depositTripleChecks(vaultId, msgValue, receiver); + } + // deposit triple + emit log_named_uint("balance currentActor", currentActor.balance); + emit log_named_uint("balance EthMultiVaultbal-", address(actEthMultiVault).balance); + emit log_named_uint("balance this--------", address(this).balance); + // logs + emit log_named_uint( + "------------------------------------ POST STATE -------------------------------------------", 6000000009 + ); + emit log_named_uint("vaultTotalShares----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets--------", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint( + "==================================== ACTOR depositTriple ====================================", shares + ); + return shares; + } + + function redeemTriple( + uint256 shares2Redeem, + address receiver, + uint256 vaultId, + uint256 msgValue, + uint256 actorIndexSeed + ) public useActor(actorIndexSeed) returns (uint256) { + numberOfCalls++; + numberOfTripleRedeems++; + emit log_named_uint( + "==================================== ACTOR redeemTriple START ====================================", + 6000000009 + ); + emit log_named_address("currentActor-----", currentActor); + emit log_named_uint("currentActor.balance", currentActor.balance); + emit log_named_uint("msgValue------------", msgValue); + // if no triple vaults exist create one and deposit on it + if (actEthMultiVault.count() == 0) { + vm.deal(currentActor, getTripleCost()); + vaultId = _createTripleChecks(msgValue, 1, 2, 3); + + msgValue = bound(msgValue, getMinDeposit(), 10 ether); + vm.deal(currentActor, msgValue); + emit log_named_uint("|||||||||||||||||||||||||||||||||||BRANCH 1|||||||||||||||||||||||||||||||||||", 1); + shares2Redeem = _depositTripleChecks(vaultId, msgValue, currentActor); + } else { + // vault exists + if (vaultId == 0 || vaultId > actEthMultiVault.count()) { + uint256[] memory tripleVaults = new uint256[](actEthMultiVault.count()); + uint256 tripleVaultsCount = 0; + for (uint256 i = 1; i <= actEthMultiVault.count(); i++) { + if (actEthMultiVault.isTripleId(i)) { + tripleVaults[tripleVaultsCount] = i; + tripleVaultsCount++; + } + } + + vaultId = tripleVaults[bound(actorIndexSeed, 0, tripleVaultsCount - 1)]; + } + + // if vault balance of the selected vault is 0, deposit minDeposit + if (getVaultBalanceForAddress(vaultId, currentActor) == 0) { + vm.deal(currentActor, 10 ether); + emit log_named_uint("vaultTShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets--", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf", getVaultBalanceForAddress(vaultId, currentActor)); + msgValue = bound(msgValue, getTripleCost(), 10 ether); + emit log_named_uint("REEEE getVaultTotalAssets(vaultId)", getVaultTotalAssets(vaultId)); + emit log_named_uint("REEEE getVaultTotalShares(vaultId)", getVaultTotalShares(vaultId)); + emit log_named_uint("|||||||||||||||||||||||||||||||BRANCH 2||||||||||||||||||||||||||||||||||||", 2); + shares2Redeem = actEthMultiVault.depositTriple{value: msgValue}(currentActor, vaultId); + _depositTripleChecks(vaultId, msgValue, receiver); + emit log_named_uint("shares2Redeem", shares2Redeem); + } else { + emit log_named_uint("|||||||||||||||||||||||||||||||BRANCH 3||||||||||||||||||||||||||||||||||||", 3); + // bound shares2Redeem to between 1 and vaultBalanceOf + shares2Redeem = bound(shares2Redeem, 1, getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint("shares2Redeem", shares2Redeem); + } + } + // use the redeemer as the receiver always + receiver = currentActor; + + emit log_named_uint("before vaultTotalShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("before vaultTAssets------", getVaultTotalShares(vaultId)); + emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); + + uint256 assetsForReceiver = _redeemTripleChecks(shares2Redeem, receiver, vaultId); + + // logs + emit log_named_uint( + "------------------------------------ POST STATE -------------------------------------------", 6000000009 + ); + emit log_named_uint("vaultTotalShares--", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTAssets------", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint( + "==================================== ACTOR redeemTriple END ====================================", + assetsForReceiver + ); + return assetsForReceiver; + } + + function _createTripleChecks(uint256 msgValue, uint256 subjectId, uint256 predicateId, uint256 objectId) + internal + returns (uint256 vaultId) + { + uint256 totalAssetsBefore = vaultTotalAssets(ethMultiVault.count() + 1); + uint256 totalSharesBefore = vaultTotalShares(ethMultiVault.count() + 1); + + uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; + + uint256[3] memory totalAssetsBeforeAtomVaults = + [vaultTotalAssets(subjectId), vaultTotalAssets(predicateId), vaultTotalAssets(objectId)]; + uint256[3] memory totalSharesBeforeAtomVaults = + [vaultTotalShares(subjectId), vaultTotalShares(predicateId), vaultTotalShares(objectId)]; + + // create triple + vaultId = actEthMultiVault.createTriple{value: msgValue}(subjectId, predicateId, objectId); + assertEq(vaultId, actEthMultiVault.count()); + + checkDepositOnTripleVaultCreation(vaultId, msgValue, totalAssetsBefore, totalSharesBefore); + + // snapshots after creating a triple + assertEq( + protocolVaultBalanceBefore, + // protocolVaultBalanceAfterLessFees + address(getProtocolVault()).balance - protocolFeeAmount(msgValue - getTripleCost(), vaultId) + - getTripleCreationProtocolFee() + ); + + _checkUnderlyingAtomDepositsOnTripleCreation( + [subjectId, predicateId, objectId], + totalAssetsBeforeAtomVaults, + totalSharesBeforeAtomVaults, + msgValue - getTripleCost() + ); + } + + function _checkUnderlyingAtomDepositsOnTripleCreation( + uint256[3] memory atomIds, + uint256[3] memory totalAssetsBeforeAtomVaults, + uint256[3] memory totalSharesBeforeAtomVaults, + uint256 userDeposit + ) internal { + uint256 protocolDepositFee = protocolFeeAmount(userDeposit, atomIds[0]); + uint256 userDepositAfterProtocolFees = userDeposit - protocolDepositFee; + + uint256 atomDepositFraction = atomDepositFractionAmount(userDepositAfterProtocolFees, atomIds[0]); + uint256 distributeAmountPerAtomVault = atomDepositFraction / 3; + + uint256 atomDepositFractionOnTripleCreationPerAtom = getAtomDepositFractionOnTripleCreation() / 3; + + for (uint256 i = 0; i < 3; i++) { + checkAtomDepositIntoVaultOnTripleVaultCreation( + distributeAmountPerAtomVault, + atomDepositFractionOnTripleCreationPerAtom, + atomIds[i], + totalAssetsBeforeAtomVaults[i], + totalSharesBeforeAtomVaults[i] + ); + } + } + + function _depositTripleChecks(uint256 vaultId, uint256 msgValue, address receiver) + internal + returns (uint256 shares) + { + uint256 totalAssetsBefore = vaultTotalAssets(vaultId); + uint256 totalSharesBefore = vaultTotalShares(vaultId); + + uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; + + (uint256 subjectId, uint256 predicateId, uint256 objectId) = actEthMultiVault.getTripleAtoms(vaultId); + + uint256[3] memory totalAssetsBeforeAtomVaults = + [vaultTotalAssets(subjectId), vaultTotalAssets(predicateId), vaultTotalAssets(objectId)]; + uint256[3] memory totalSharesBeforeAtomVaults = + [vaultTotalShares(subjectId), vaultTotalShares(predicateId), vaultTotalShares(objectId)]; + + // deposit triple + shares = actEthMultiVault.depositTriple{value: msgValue}(receiver, vaultId); + + uint256 userDepositAfterProtocolFees = msgValue - getProtocolFeeAmount(msgValue, vaultId); + + checkDepositIntoVault(userDepositAfterProtocolFees, vaultId, totalAssetsBefore, totalSharesBefore); + + checkProtocolVaultBalance(vaultId, msgValue, protocolVaultBalanceBefore); + + uint256 amountToDistribute = atomDepositFractionAmount(userDepositAfterProtocolFees, vaultId); + uint256 distributeAmountPerAtomVault = amountToDistribute / 3; + + checkDepositIntoVault( + distributeAmountPerAtomVault, subjectId, totalAssetsBeforeAtomVaults[0], totalSharesBeforeAtomVaults[0] + ); + + checkDepositIntoVault( + distributeAmountPerAtomVault, predicateId, totalAssetsBeforeAtomVaults[1], totalSharesBeforeAtomVaults[1] + ); + + checkDepositIntoVault( + distributeAmountPerAtomVault, objectId, totalAssetsBeforeAtomVaults[2], totalSharesBeforeAtomVaults[2] + ); + } + + function _redeemTripleChecks(uint256 shares2Redeem, address receiver, uint256 vaultId) + internal + returns (uint256 assetsForReceiver) + { + // snapshots before redeem + uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; + uint256 userSharesBeforeRedeem = getSharesInVault(vaultId, receiver); + uint256 userBalanceBeforeRedeem = address(receiver).balance; + + uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, vaultId); + // redeem triple + assetsForReceiver = actEthMultiVault.redeemTriple(shares2Redeem, receiver, vaultId); + + checkProtocolVaultBalance(vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); + + assertEq(getSharesInVault(vaultId, receiver), userSharesBeforeRedeem - shares2Redeem); + assertEq(address(receiver).balance - userBalanceBeforeRedeem, assetsForReceiver); + } } diff --git a/test/invariant/actors/EthMultiVaultSingleVaultActor.sol b/test/invariant/actors/EthMultiVaultSingleVaultActor.sol index 4dccd80f..090f214d 100644 --- a/test/invariant/actors/EthMultiVaultSingleVaultActor.sol +++ b/test/invariant/actors/EthMultiVaultSingleVaultActor.sol @@ -16,8 +16,10 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { // ghost variables uint256 public numberOfCalls; - uint256 public numberOfDeposits; - uint256 public numberOfRedeems; + uint256 public numberOfAtomDeposits; + uint256 public numberOfAtomRedeems; + uint256 public numberOfTripleDeposits; + uint256 public numberOfTripleRedeems; modifier useActor(uint256 actorIndexSeed) { currentActor = actors[bound(actorIndexSeed, 0, actors.length - 1)]; @@ -33,11 +35,10 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { actorPks.push(i + 1); actors.push(vm.addr(actorPks[i])); } - //vm.deal(actors[0], 1 ether); - //vm.prank(actors[0]); - //actEthMultiVault.createAtom{value: actEthMultiVault.getAtomCost()}("PEPE"); } + receive() external payable {} + function getVaultTotalAssets(uint256 vaultId) public view returns (uint256 totalAssets) { (totalAssets,) = actEthMultiVault.vaults(vaultId); } @@ -57,13 +58,13 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { return calculatedAssetsForReceiver + protocolFees + exitFees; } - function depositAtom(address _receiver, uint256 msgValue, uint256 actorIndexSeed) + function depositAtom(address receiver, uint256 msgValue, uint256 actorIndexSeed) public useActor(actorIndexSeed) returns (uint256) { numberOfCalls++; - numberOfDeposits++; + numberOfAtomDeposits++; emit log_named_uint( "==================================== ACTOR depositAtom START ====================================", 6000000009 @@ -71,29 +72,29 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { emit log_named_address("currentActor-----", currentActor); emit log_named_uint("currentActor.balance", currentActor.balance); emit log_named_uint("msgValue------------", msgValue); - uint256 _vaultId = 1; - emit log_named_uint("vaultTotalAssets----", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultTotalShares----", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(_vaultId, currentActor)); - // bound _receiver to msg.sender always - _receiver = currentActor; + uint256 vaultId = 1; + emit log_named_uint("vaultTotalAssets----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + // bound receiver to msg.sender always + receiver = currentActor; // bound msgValue to between minDeposit and 10 ether msgValue = bound(msgValue, getAtomCost(), 10 ether); vm.deal(currentActor, msgValue); - uint256 totalAssetsBefore = vaultTotalAssets(_vaultId); - uint256 totalSharesBefore = vaultTotalShares(_vaultId); + uint256 totalAssetsBefore = vaultTotalAssets(vaultId); + uint256 totalSharesBefore = vaultTotalShares(vaultId); uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; // deposit atom - uint256 shares = actEthMultiVault.depositAtom{value: msgValue}(_receiver, _vaultId); + uint256 shares = actEthMultiVault.depositAtom{value: msgValue}(receiver, vaultId); checkDepositIntoVault( - msgValue - getProtocolFeeAmount(msgValue, _vaultId), _vaultId, totalAssetsBefore, totalSharesBefore + msgValue - getProtocolFeeAmount(msgValue, vaultId), vaultId, totalAssetsBefore, totalSharesBefore ); - checkProtocolVaultBalance(_vaultId, msgValue, protocolVaultBalanceBefore); + checkProtocolVaultBalance(vaultId, msgValue, protocolVaultBalanceBefore); // logs emit log_named_uint( @@ -102,22 +103,22 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { emit log_named_uint("balance currentActor", currentActor.balance); emit log_named_uint("balance EthMultiVaultbal-", address(actEthMultiVault).balance); emit log_named_uint("balance this--------", address(this).balance); - emit log_named_uint("vaultTotalShares----", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultTAssets--------", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTotalShares----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTAssets--------", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); emit log_named_uint( "==================================== ACTOR depositAtom END ====================================", shares ); return shares; } - function redeemAtom(uint256 _shares2Redeem, address _receiver, uint256 msgValue, uint256 actorIndexSeed) + function redeemAtom(uint256 shares2Redeem, address receiver, uint256 msgValue, uint256 actorIndexSeed) public useActor(actorIndexSeed) returns (uint256) { numberOfCalls++; - numberOfRedeems++; + numberOfAtomRedeems++; emit log_named_uint( "==================================== ACTOR redeemAtom START ====================================", 6000000009 @@ -125,51 +126,51 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { emit log_named_address("currentActor-----", currentActor); emit log_named_uint("currentActor.balance", currentActor.balance); emit log_named_uint("msgValue------------", msgValue); - uint256 _vaultId = 1; + uint256 vaultId = 1; // if vault balance of the selected vault is 0, deposit minDeposit - if (getVaultBalanceForAddress(_vaultId, currentActor) == 0) { + if (getVaultBalanceForAddress(vaultId, currentActor) == 0) { vm.deal(currentActor, 10 ether); msgValue = bound(msgValue, getAtomCost(), 10 ether); - _shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, _vaultId); - emit log_named_uint("_shares2Redeem", _shares2Redeem); + shares2Redeem = actEthMultiVault.depositAtom{value: msgValue}(currentActor, vaultId); + emit log_named_uint("shares2Redeem", shares2Redeem); } else { - // bound _shares2Redeem to between 1 and vaultBalanceOf - _shares2Redeem = bound(_shares2Redeem, 1, getVaultBalanceForAddress(_vaultId, currentActor)); - emit log_named_uint("_shares2Redeem", _shares2Redeem); + // bound shares2Redeem to between 1 and vaultBalanceOf + shares2Redeem = bound(shares2Redeem, 1, getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint("shares2Redeem", shares2Redeem); } // use the redeemer as the receiver always - _receiver = currentActor; + receiver = currentActor; - emit log_named_uint("before vaultTotalShares--", getVaultTotalShares(_vaultId)); - emit log_named_uint("before vaultTAssets------", getVaultTotalAssets(_vaultId)); - emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("before vaultTotalShares--", getVaultTotalShares(vaultId)); + emit log_named_uint("before vaultTAssets------", getVaultTotalAssets(vaultId)); + emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); // snapshots before redeem uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; - uint256 userSharesBeforeRedeem = getSharesInVault(_vaultId, _receiver); - uint256 userBalanceBeforeRedeem = address(_receiver).balance; + uint256 userSharesBeforeRedeem = getSharesInVault(vaultId, receiver); + uint256 userBalanceBeforeRedeem = address(receiver).balance; - uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, _vaultId); + uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, vaultId); // redeem atom - uint256 assetsForReceiver = actEthMultiVault.redeemAtom(_shares2Redeem, _receiver, _vaultId); + uint256 assetsForReceiver = actEthMultiVault.redeemAtom(shares2Redeem, receiver, vaultId); - checkProtocolVaultBalance(_vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); + checkProtocolVaultBalance(vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); // snapshots after redeem - uint256 userSharesAfterRedeem = getSharesInVault(_vaultId, _receiver); - uint256 userBalanceAfterRedeem = address(_receiver).balance; + uint256 userSharesAfterRedeem = getSharesInVault(vaultId, receiver); + uint256 userBalanceAfterRedeem = address(receiver).balance; - assertEq(userSharesAfterRedeem, userSharesBeforeRedeem - _shares2Redeem); + assertEq(userSharesAfterRedeem, userSharesBeforeRedeem - shares2Redeem); assertEq(userBalanceAfterRedeem - userBalanceBeforeRedeem, assetsForReceiver); // logs emit log_named_uint( "------------------------------------ POST STATE -------------------------------------------", 6000000009 ); - emit log_named_uint("vaultTotalShares--", getVaultTotalShares(_vaultId)); - emit log_named_uint("vaultTAssets------", getVaultTotalAssets(_vaultId)); - emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(_vaultId, currentActor)); + emit log_named_uint("vaultTotalShares--", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTAssets------", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); emit log_named_uint( "==================================== ACTOR redeemAtom END ====================================", assetsForReceiver @@ -177,5 +178,155 @@ contract EthMultiVaultSingleVaultActor is Test, EthMultiVaultHelpers { return assetsForReceiver; } - receive() external payable {} + function depositTriple(address receiver, uint256 msgValue, uint256 actorIndexSeed) + public + useActor(actorIndexSeed) + returns (uint256) + { + numberOfCalls++; + numberOfTripleDeposits++; + emit log_named_uint( + "==================================== ACTOR depositTriple START ====================================", + 6000000009 + ); + emit log_named_address("currentActor-----", currentActor); + emit log_named_uint("currentActor.balance", currentActor.balance); + emit log_named_uint("msgValue------------", msgValue); + uint256 vaultId = 4; + emit log_named_uint("vaultTotalAssets----", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultTotalShares----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + // bound receiver to msg.sender always + receiver = currentActor; + // bound msgValue to between minDeposit and 10 ether + msgValue = bound(msgValue, getTripleCost(), 10 ether); + vm.deal(currentActor, msgValue); + + // deposit triple + uint256 shares = _depositTripleChecks(vaultId, msgValue, receiver); + + // logs + emit log_named_uint( + "------------------------------------ POST STATE -------------------------------------------", 6000000009 + ); + emit log_named_uint("balance currentActor", currentActor.balance); + emit log_named_uint("balance EthMultiVaultbal-", address(actEthMultiVault).balance); + emit log_named_uint("balance this--------", address(this).balance); + emit log_named_uint("vaultTotalShares----", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTAssets--------", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf------", getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint( + "==================================== ACTOR depositTriple END ====================================", shares + ); + return shares; + } + + function redeemTriple(uint256 shares2Redeem, address receiver, uint256 msgValue, uint256 actorIndexSeed) + public + useActor(actorIndexSeed) + returns (uint256) + { + numberOfCalls++; + numberOfTripleRedeems++; + emit log_named_uint( + "==================================== ACTOR redeemTriple START ====================================", + 6000000009 + ); + emit log_named_address("currentActor-----", currentActor); + emit log_named_uint("currentActor.balance", currentActor.balance); + emit log_named_uint("msgValue------------", msgValue); + uint256 vaultId = 4; + // if vault balance of the selected vault is 0, deposit minDeposit + if (getVaultBalanceForAddress(vaultId, currentActor) == 0) { + vm.deal(currentActor, 10 ether); + msgValue = bound(msgValue, getTripleCost(), 10 ether); + shares2Redeem = actEthMultiVault.depositTriple{value: msgValue}(currentActor, vaultId); + emit log_named_uint("shares2Redeem", shares2Redeem); + } else { + // bound shares2Redeem to between 1 and vaultBalanceOf + shares2Redeem = bound(shares2Redeem, 1, getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint("shares2Redeem", shares2Redeem); + } + // use the redeemer as the receiver always + receiver = currentActor; + + emit log_named_uint("before vaultTotalShares--", getVaultTotalShares(vaultId)); + emit log_named_uint("before vaultTAssets------", getVaultTotalAssets(vaultId)); + emit log_named_uint("before vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); + + // redeem triple + uint256 assetsForReceiver = _redeemTripleChecks(shares2Redeem, receiver, vaultId); + + // logs + emit log_named_uint( + "------------------------------------ POST STATE -------------------------------------------", 6000000009 + ); + emit log_named_uint("vaultTotalShares--", getVaultTotalShares(vaultId)); + emit log_named_uint("vaultTAssets------", getVaultTotalAssets(vaultId)); + emit log_named_uint("vaultBalanceOf----", getVaultBalanceForAddress(vaultId, currentActor)); + emit log_named_uint( + "==================================== ACTOR redeemTriple END ====================================", + assetsForReceiver + ); + return assetsForReceiver; + } + + function _depositTripleChecks(uint256 vaultId, uint256 msgValue, address receiver) + internal + returns (uint256 shares) + { + uint256 totalAssetsBefore = vaultTotalAssets(vaultId); + uint256 totalSharesBefore = vaultTotalShares(vaultId); + + uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; + + (uint256 subjectId, uint256 predicateId, uint256 objectId) = actEthMultiVault.getTripleAtoms(vaultId); + + uint256[3] memory totalAssetsBeforeAtomVaults = + [vaultTotalAssets(subjectId), vaultTotalAssets(predicateId), vaultTotalAssets(objectId)]; + uint256[3] memory totalSharesBeforeAtomVaults = + [vaultTotalShares(subjectId), vaultTotalShares(predicateId), vaultTotalShares(objectId)]; + + shares = actEthMultiVault.depositTriple{value: msgValue}(receiver, vaultId); + + uint256 userDepositAfterProtocolFees = msgValue - getProtocolFeeAmount(msgValue, vaultId); + + checkDepositIntoVault(userDepositAfterProtocolFees, vaultId, totalAssetsBefore, totalSharesBefore); + + checkProtocolVaultBalance(vaultId, msgValue, protocolVaultBalanceBefore); + + uint256 amountToDistribute = atomDepositFractionAmount(userDepositAfterProtocolFees, vaultId); + uint256 distributeAmountPerAtomVault = amountToDistribute / 3; + + checkDepositIntoVault( + distributeAmountPerAtomVault, subjectId, totalAssetsBeforeAtomVaults[0], totalSharesBeforeAtomVaults[0] + ); + + checkDepositIntoVault( + distributeAmountPerAtomVault, predicateId, totalAssetsBeforeAtomVaults[1], totalSharesBeforeAtomVaults[1] + ); + + checkDepositIntoVault( + distributeAmountPerAtomVault, objectId, totalAssetsBeforeAtomVaults[2], totalSharesBeforeAtomVaults[2] + ); + } + + function _redeemTripleChecks(uint256 shares2Redeem, address receiver, uint256 vaultId) + internal + returns (uint256 assetsForReceiver) + { + // snapshots before redeem + uint256 protocolVaultBalanceBefore = address(getProtocolVault()).balance; + uint256 userSharesBeforeRedeem = getSharesInVault(vaultId, receiver); + uint256 userBalanceBeforeRedeem = address(receiver).balance; + + uint256 assetsForReceiverBeforeFees = getAssetsForReceiverBeforeFees(userSharesBeforeRedeem, vaultId); + // redeem triple + assetsForReceiver = actEthMultiVault.redeemTriple(shares2Redeem, receiver, vaultId); + + checkProtocolVaultBalance(vaultId, assetsForReceiverBeforeFees, protocolVaultBalanceBefore); + + assertEq(getSharesInVault(vaultId, receiver), userSharesBeforeRedeem - shares2Redeem); + assertEq(address(receiver).balance - userBalanceBeforeRedeem, assetsForReceiver); + } }