Skip to content

Commit

Permalink
test: run medusa fuzzing campaign from within foundry
Browse files Browse the repository at this point in the history
  • Loading branch information
0xteddybear committed Aug 30, 2024
1 parent eaf38e3 commit c80fb58
Showing 1 changed file with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,83 @@ pragma solidity 0.8.25;

// Testing utilities
import { Test, StdUtils, Vm } from "forge-std/Test.sol";
import { StdInvariant } from "forge-std/StdInvariant.sol";
import { StdAssertions } from "forge-std/StdAssertions.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";

// Libraries
import { Predeploys } from "src/libraries/Predeploys.sol";
import { OptimismSuperchainERC20 } from "src/L2/OptimismSuperchainERC20.sol";
import { IL2ToL2CrossDomainMessenger } from "src/L2/IL2ToL2CrossDomainMessenger.sol";
import { ProtocolGuided } from "../properties/medusa/fuzz/Protocol.guided.t.sol";
import { ProtocolUnguided } from "../properties/medusa/fuzz/Protocol.unguided.t.sol";
import { FoundryGetters } from "../properties/helpers/FoundryGetters.t.sol";
import { MockL2ToL2CrossDomainMessenger } from "../properties/helpers/MockL2ToL2CrossDomainMessenger.t.sol";

contract MedusaCampaignHandler is FoundryGetters, ProtocolGuided, ProtocolUnguided { }

contract OptimismSuperchainERC20MedusaProperties is Test {
MedusaCampaignHandler internal handler;
MockL2ToL2CrossDomainMessenger internal constant MESSENGER =
MockL2ToL2CrossDomainMessenger(Predeploys.L2_TO_L2_CROSS_DOMAIN_MESSENGER);

function setUp() public {
handler = new MedusaCampaignHandler();
targetContract(address(handler));
}

// TODO: will need rework after
// - `convert`
/// @custom:property-id 19
/// @custom:property sum of supertoken total supply across all chains is always <= to convert(legacy, super)-
/// convert(super, legacy)
function invariant_totalSupplyAcrossChainsEqualsMintsMinusFundsInTransit() external view {
// iterate over unique deploy salts aka supertokens that are supposed to be compatible with each other
for (uint256 deploySaltIndex = 0; deploySaltIndex < handler.deploySaltsLength(); deploySaltIndex++) {
uint256 totalSupply = 0;
(bytes32 currentSalt, uint256 trackedSupply) = handler.totalSupplyAcrossChainsAtIndex(deploySaltIndex);
uint256 fundsInTransit = handler.tokensInTransitForDeploySalt(currentSalt);
// and then over all the (mocked) chain ids where that supertoken could be deployed
for (uint256 validChainId = 0; validChainId < handler.MAX_CHAINS(); validChainId++) {
address supertoken = MESSENGER.superTokenAddresses(validChainId, currentSalt);
if (supertoken != address(0)) {
totalSupply += OptimismSuperchainERC20(supertoken).totalSupply();
}
}
assertEq(trackedSupply, totalSupply + fundsInTransit);
}
}

// TODO: will need rework after
// - `convert`
/// @custom:property-id 21
/// @custom:property sum of supertoken total supply across all chains is equal to convert(legacy, super)-
/// convert(super, legacy) when all when all cross-chain messages are processed
function invariant_totalSupplyAcrossChainsEqualsMintsWhenQueueIsEmpty() external view {
if (MESSENGER.messageQueueLength() != 0) {
return;
}
// iterate over unique deploy salts aka supertokens that are supposed to be compatible with each other
for (uint256 deploySaltIndex = 0; deploySaltIndex < handler.deploySaltsLength(); deploySaltIndex++) {
uint256 totalSupply = 0;
(bytes32 currentSalt, uint256 trackedSupply) = handler.totalSupplyAcrossChainsAtIndex(deploySaltIndex);
// and then over all the (mocked) chain ids where that supertoken could be deployed
for (uint256 validChainId = 0; validChainId < handler.MAX_CHAINS(); validChainId++) {
address supertoken = MESSENGER.superTokenAddresses(validChainId, currentSalt);
if (supertoken != address(0)) {
totalSupply += OptimismSuperchainERC20(supertoken).totalSupply();
}
}
assertEq(trackedSupply, totalSupply);
}
}

///@notice `fail_on_revert=false` also ignores StdAssertion failures, so we
/// can't simply override compatibleAssert to call StdAssertions.assertTrue
function invariant_handlerAssertions() external view {
assertFalse(handler.failed());
}
}

/// @title OptimismSuperchainERC20_User
/// @notice Actor contract that interacts with the OptimismSuperchainERC20 contract.
Expand Down

0 comments on commit c80fb58

Please sign in to comment.