Skip to content
Open

V2 #129

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2db6f81
feat: post-deploy v2 prep (#96)
deluca-mike Jan 21, 2025
d0f6c8c
feat: `wrapWithPermit` (#98)
deluca-mike Jan 21, 2025
86abe79
feat: `setClaimRecipient` (#99)
deluca-mike Feb 6, 2025
442817b
feat: principal-based account (#108)
deluca-mike Feb 14, 2025
fb67a31
feat: cheaper earner-earner/nonEarner-nonEarner transfers (#107)
deluca-mike Feb 14, 2025
79264af
feat: favour user and track rounding error (#109)
deluca-mike Feb 14, 2025
a69eb5f
feat: No claim on wrap/unwrap/transfer (#105)
deluca-mike Feb 14, 2025
7313eb9
feat: Earner Manager (#100)
deluca-mike Feb 14, 2025
daa7e03
feat: test earner accounts involved in migraation (#111)
deluca-mike Mar 1, 2025
5aa9684
Rebase on main v2 branch (#115)
toninorair Mar 3, 2025
1ed3ab3
Fixes after Blackthorn and internal audits (#117)
toninorair Mar 14, 2025
5851bab
Excess fixes after reviews (#119)
toninorair Mar 17, 2025
c15bc30
Chainsecurity review fixes (#121)
toninorair Apr 4, 2025
f79af77
Return vs revert if excess == 0 (#122)
toninorair Apr 8, 2025
296a42b
feat: use SwapFacility (#123)
0xIryna Dec 16, 2025
af67fce
fix(WrappedMToken): remove EarnerManager (#124)
PierrickGT Dec 16, 2025
5e93dfa
feat(WrappedM): add Pausable and Freezable (#125)
PierrickGT Dec 16, 2025
9a9f0ea
feat(WrappedM): mint WM to excess destination instead of M (#126)
PierrickGT Dec 16, 2025
81d97a1
chore(script): add script to retrieve WM earners (#127)
PierrickGT Feb 13, 2026
5517ff8
feat(WrappedM): add forceTransfer functionality with FORCED_TRANSFER_…
PierrickGT May 31, 2026
699860f
fix(WrappedM): fix frozen check inconsistencies (#130)
PierrickGT Jun 5, 2026
c6327a2
feat(WrappedM): add EXCESS_MANAGER_ROLE and settable excessDestinatio…
PierrickGT Jun 5, 2026
ef53e13
chore(lib): update common to v1.5.2
PierrickGT Jun 10, 2026
145a681
fix(WrappedM): address internal review findings (I-01, I-02, I-03) (#…
PierrickGT Jun 12, 2026
aa6dc9d
fix(WrappedM): address ChainSecurity audit issues (#133)
PierrickGT Jun 19, 2026
4716596
fix(WrappedM): address remaining ChainSecurity audit issues (#134)
PierrickGT Jun 24, 2026
d2374be
fix(WrappedM): chain OpenZeppelin PausableUpgradeable initializer
PierrickGT Jun 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .env.deploy.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Deploy script environment variables
PRIVATE_KEY= # Private key of the deployer
DEPLOYER= # Address of the deployer
DEPLOYER_PROXY_NONCE= # Nonce of the deployer when creating the Wrapped M proxy
EXPECTED_PROXY= # Address of the expected Wrapped M proxy
M_TOKEN= # Address of the M token
REGISTRAR= # Address of the Registrar
EXCESS_DESTINATION= # Address of the Excess Destination
SWAP_FACILITY= # Address of the Swap Facility
MIGRATION_ADMIN= # Address of the Migration Admin

# RPC URL to deploy to
DEPLOY_RPC_URL=

# Used for verifying contracts on Etherscan
ETHERSCAN_API_KEY=
8 changes: 4 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Localhost RPC URL
export LOCALHOST_RPC_URL=http://127.0.0.1:8545
LOCALHOST_RPC_URL=http://127.0.0.1:8545

# Mainnet RPC URLs
export MAINNET_RPC_URL=
MAINNET_RPC_URL=

# Testnet RPC URLs
export SEPOLIA_RPC_URL=
SEPOLIA_RPC_URL=

# Used for verifying contracts on Etherscan
export ETHERSCAN_API_KEY=
ETHERSCAN_API_KEY=
8 changes: 8 additions & 0 deletions .env.upgrade.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Mainnet upgrade script environment variables
PRIVATE_KEY= # Private key of the deployer

# Mainnet RPC URL to perform upgrade
MAINNET_RPC_URL=

# Used for verifying contracts on Etherscan
ETHERSCAN_API_KEY=
2 changes: 1 addition & 1 deletion .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: make coverage

- name: Report code coverage
uses: zgosalvez/github-actions-report-lcov@v3
uses: zgosalvez/github-actions-report-lcov@v4.1.22
with:
coverage-files: lcov.info
artifact-name: code-coverage-report
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-gas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
run: make gas-report

- name: Compare gas reports
uses: Rubilmax/foundry-gas-diff@v3.16
uses: Rubilmax/foundry-gas-diff@v3.21
id: gas_diff

- name: Add gas diff to sticky comment
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ docs/
# NPM modules
node_modules
gasreport.ansi

#soljson
soljson-latest.js
8 changes: 6 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
[submodule "lib/forge-std"]
path = lib/forge-std
url = git@github.com:foundry-rs/forge-std.git
url = https://github.com/foundry-rs/forge-std
branch = v1
[submodule "lib/common"]
path = lib/common
url = git@github.com:MZero-Labs/common.git
url = https://github.com/m0-foundation/common
branch = release-v1.5.2
[submodule "lib/evm-m-extensions"]
path = lib/evm-m-extensions
url = https://github.com/m0-foundation/evm-m-extensions
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"files": "*.sol",
"options": {
"bracketSpacing": true,
"compiler": "0.8.23",
"compiler": "0.8.26",
"parser": "solidity-parse",
"printWidth": 120,
"tabWidth": 4,
Expand Down
2 changes: 1 addition & 1 deletion .solhint.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
],
"compiler-version": [
"error",
"0.8.23"
"0.8.26"
],
"comprehensive-interface": "off",
"const-name-snakecase": "off",
Expand Down
11 changes: 7 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@ update:; forge update

# Deployment helpers
deploy:
FOUNDRY_PROFILE=production forge script script/DeployProduction.s.sol --skip src --skip test --rpc-url mainnet --slow --broadcast -vvv --verify
FOUNDRY_PROFILE=production forge script script/Deploy.s.sol --skip src --skip test --rpc-url ${DEPLOY_RPC_URL} --etherscan-api-key ${ETHERSCAN_API_KEY} --slow --broadcast -vvv --verify --show-standard-json-input

deploy-local:
FOUNDRY_PROFILE=production forge script script/DeployProduction.s.sol --skip src --skip test --rpc-url localhost --slow --broadcast -vvv
FOUNDRY_PROFILE=production forge script script/Deploy.s.sol --skip src --skip test --rpc-url localhost --slow --broadcast -vvv

deploy-upgrade:
FOUNDRY_PROFILE=production forge script script/DeployUpgradeMainnet.s.sol --skip src --skip test --rpc-url mainnet --slow --broadcast -vvv --verify --show-standard-json-input

# Run slither
slither :
Expand All @@ -35,10 +38,10 @@ invariant:
MAINNET_RPC_URL=$(MAINNET_RPC_URL) ./test.sh -d test/invariant -p $(profile)

coverage:
MAINNET_RPC_URL=$(MAINNET_RPC_URL) forge coverage --no-match-path 'test/in*/**/*.sol' --report lcov && lcov --extract lcov.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 -o lcov.info 'src/*' && genhtml lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 -o coverage
FOUNDRY_PROFILE=production forge coverage --fork-url $(MAINNET_RPC_URL) --report lcov && lcov --extract lcov.info --rc lcov_branch_coverage=1 --rc derive_function_end_line=0 -o lcov.info 'src/*' && genhtml lcov.info --rc branch_coverage=1 --rc derive_function_end_line=0 -o coverage

gas-report:
FOUNDRY_PROFILE=production forge test --no-match-path 'test/integration/**/*.sol' --gas-report > gasreport.ansi
FOUNDRY_PROFILE=production forge test --fork-url $(MAINNET_RPC_URL) --gas-report > gasreport.ansi

sizes:
./build.sh -p production -s
Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ You may have to install the following tools to use this repository:

- [foundry](https://github.com/foundry-rs/foundry) to compile and test contracts
- [lcov](https://github.com/linux-test-project/lcov) to generate the code coverage report
- [yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to manage node dependencies
- [slither](https://github.com/crytic/slither) to static analyze contracts

Install dependencies:
Expand Down
4 changes: 4 additions & 0 deletions earners/arbitrum.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
address,balance
0x0a1a1a107e45b7ced86833863f482bc5f4ed82ef,678979424224816
0x0b2b2b2076d95dda7817e785989fe353fe955ef9,6094692055093
0xb50a1f651a5acb2679c8f679d782c728f3702e53,6039117591036
25 changes: 25 additions & 0 deletions earners/ethereum.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
address,balance
0x4cbc25559dbbd1272ec5b64c7b5f48a2405e6470,68218629706363
0xff95c5f35f4ffb9d5f596f898ac1ae38d62749c2,14498026276966
0x0502d65f26f45d17503e4d34441f5e73ea143033,2576885412528
0x970a7749ecaa4394c8b2bf5f2471f41fd6b79288,2335445266321
0x81ad394c0fa87e99ca46e1aca093bee020f203f4,73701877312
0xfe940bfe535013a52e8e2df9644f95e3c94fa14b,23142486046
0xe0663f2372caa1459b7ade90812dc737ce587fa6,6847088454
0xa969cfcd9e583edb8c8b270dc8cafb33d6cf662d,3080743473
0x9c6e67fa86138ab49359f595bfe4fb163d0f16cc,2536640986
0xdd82875f0840aad58a455a70b88eed9f59cec7c7,1702276055
0xb65a66621d7de34afec9b9ac0755133051550dd7,891681763
0xcad001c30e96765ac90307669d578219d4fb1dce,85322234
0xded796de6a14e255487191963dee436c45995813,66920585
0xea0c048c728578b1510ebdf9b692e8936d6fbc90,34057216
0xbbbbbbbbbb9cc5e90e3b3af64bdaf62c37eeffcb,7137461
0x13ccb6e28f22e2f6783badedce32cc74583a3647,337592
0x985de23260743c2c2f09bfdec50b048c7a18c461,287386
0x7db685961f97c847a4c815d43e9cc0e5647328b9,41793
0x48afe17cb6363fd1aaea50a8cb652c5978972c96,1931
0xe72fe64840f4ef80e3ec73a1c749491b5c938cb9,988
0xcf3166181848eec4fd3b9046ae7cb582f34d2e6c,0
0xb50a1f651a5acb2679c8f679d782c728f3702e53,0
0x9f6d1a62bf268aa05a1218cfc89c69833d2d2a70,0
0x569d7dccbf6923350521ecbc28a555a500c4f0ec,0
130 changes: 130 additions & 0 deletions earners/get-earners.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env tsx

import { writeFileSync, mkdirSync } from "fs";
import { join } from "path";

interface WMHolder {
address: string;
balance: string;
isEarning: boolean;
}

interface GraphQLResponse {
data?: {
WMHolders?: WMHolder[];
WMHoldersArbitrum?: WMHolder[];
};
errors?: Array<{ message: string }>;
}

const PROTOCOL_API_URL = "https://protocol-api.m0.org/graphql";

async function fetchWMHolders(network: string): Promise<WMHolder[]> {
const fieldName = network === "ethereum" ? "WMHolders" : "WMHoldersL2";
const chainArg =
network === "ethereum" ? "" : `chain: ${network.toUpperCase()}`;

const query = `
query GetWMHolders {
${fieldName}(first: 1000, ${chainArg}) {
address
balance
isEarning
}
}
`;

const response = await fetch(PROTOCOL_API_URL, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ query }),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const result: GraphQLResponse = await response.json();

if (result.errors) {
throw new Error(
`GraphQL errors: ${result.errors.map((e) => e.message).join(", ")}`,
);
}

return result.data?.[fieldName as keyof GraphQLResponse["data"]] || [];
}

function convertToCSV(holders: WMHolder[]): string {
const headers = ["address", "balance"];
const rows = holders.map((holder) => [holder.address, holder.balance]);

return [headers, ...rows].map((row) => row.join(",")).join("\n");
}

async function main() {
const networks = [
"arbitrum",
"base",
"bsc",
"ethereum",
"hyperevm",
"linea",
"mantra",
"optimism",
"plasma",
"plume",
"soneium",
];

mkdirSync("earners", { recursive: true });

for (const network of networks) {
const networkName = network.charAt(0).toUpperCase() + network.slice(1);

try {
console.log(`\nFetching WrappedM holders from ${networkName}...`);

const holders = await fetchWMHolders(network);
console.log(`Found ${holders.length} WrappedM holders on ${networkName}`);

if (holders.length === 0) {
console.log("No holders found");
continue;
}

const earners = holders.filter((holder) => holder.isEarning);
console.log(
`Found ${earners.length} WrappedM earners (isEarning = true)`,
);

if (earners.length === 0) {
console.log("No earners found");
continue;
}

const csvPath = join("earners", `${network}.csv`);
const csvContent = convertToCSV(earners);

writeFileSync(csvPath, csvContent);
console.log(`Exported ${earners.length} earners to ${csvPath}`);

const totalBalance = earners.reduce(
(sum, h) => sum + parseFloat(h.balance || "0"),
0,
);

console.log(`Total balance: ${totalBalance}`);
console.log(`Total earners: ${earners.length}`);
} catch (error) {
console.error(
`Error processing ${networkName}:`,
error instanceof Error ? error.message : error,
);
}
}
}

main();
2 changes: 2 additions & 0 deletions earners/plume.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
address,balance
0xe72fe64840f4ef80e3ec73a1c749491b5c938cb9,749816515
17 changes: 17 additions & 0 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"lib/common": {
"branch": {
"name": "release-v1.5.2",
"rev": "489fae6daecd227616155e4f8cacfd17aeb3e2a1"
}
},
"lib/evm-m-extensions": {
"rev": "87a2f42ab55b5e10771f48fa0d5994bfaa3dca09"
},
"lib/forge-std": {
"branch": {
"name": "v1",
"rev": "620536fa5277db4e3fd46772d5cbc1ea0696fb43"
}
}
}
13 changes: 7 additions & 6 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
gas_reports = ["*"]
gas_reports_ignore = []
ignored_error_codes = []
solc_version = "0.8.23"
solc_version = "0.8.26"
optimizer = true
optimizer_runs = 999999
optimizer_runs = 4150
verbosity = 3
block_number = 20_270_778
block_timestamp = 1_720_550_400
fork_block_number = 20_270_778
fork_block_number = 23_170_985
rpc_storage_caching = { chains = ["mainnet"], endpoints = "all" }
evm_version = "shanghai"
evm_version = "cancun"

[lint]
lint_on_build = false

[profile.production]
build_info = true
Expand Down
2 changes: 1 addition & 1 deletion lib/common
1 change: 1 addition & 0 deletions lib/evm-m-extensions
Submodule evm-m-extensions added at 87a2f4
2 changes: 1 addition & 1 deletion lib/forge-std
Submodule forge-std updated 65 files
+1 −0 .github/CODEOWNERS
+8 −0 .github/dependabot.yml
+135 −100 .github/workflows/ci.yml
+6 −1 .github/workflows/sync.yml
+193 −0 CONTRIBUTING.md
+76 −12 README.md
+12 −0 RELEASE_CHECKLIST.md
+11 −14 foundry.toml
+2 −2 package.json
+17 −16 scripts/vm.py
+24 −11 src/Base.sol
+60 −0 src/Config.sol
+477 −0 src/LibVariable.sol
+3 −2 src/Script.sol
+691 −60 src/StdAssertions.sol
+61 −10 src/StdChains.sol
+80 −20 src/StdCheats.sol
+632 −0 src/StdConfig.sol
+30 −0 src/StdConstants.sol
+20 −2 src/StdError.sol
+43 −4 src/StdInvariant.sol
+108 −12 src/StdJson.sol
+26 −2 src/StdMath.sol
+17 −14 src/StdStorage.sol
+2 −2 src/StdStyle.sol
+114 −18 src/StdToml.sol
+6 −32 src/StdUtils.sol
+3 −4 src/Test.sol
+788 −134 src/Vm.sol
+512 −465 src/console.sol
+2 −2 src/console2.sol
+3 −3 src/interfaces/IERC1155.sol
+2 −2 src/interfaces/IERC165.sol
+2 −2 src/interfaces/IERC20.sol
+12 −12 src/interfaces/IERC4626.sol
+72 −0 src/interfaces/IERC6909.sol
+3 −3 src/interfaces/IERC721.sol
+145 −0 src/interfaces/IERC7540.sol
+241 −0 src/interfaces/IERC7575.sol
+3 −8 src/interfaces/IMulticall3.sol
+0 −234 src/mocks/MockERC20.sol
+0 −231 src/mocks/MockERC721.sol
+691 −1,380 src/safeconsole.sol
+44 −0 test/CommonBase.t.sol
+381 −0 test/Config.t.sol
+452 −0 test/LibVariable.t.sol
+3 −7 test/StdAssertions.t.sol
+43 −42 test/StdChains.t.sol
+129 −52 test/StdCheats.t.sol
+38 −0 test/StdConstants.t.sol
+15 −16 test/StdError.t.sol
+3 −3 test/StdJson.t.sol
+12 −22 test/StdMath.t.sol
+96 −35 test/StdStorage.t.sol
+3 −3 test/StdStyle.t.sol
+3 −3 test/StdToml.t.sol
+25 −25 test/StdUtils.t.sol
+11 −8 test/Vm.t.sol
+3 −5 test/compilation/CompilationScript.sol
+3 −5 test/compilation/CompilationScriptBase.sol
+3 −5 test/compilation/CompilationTest.sol
+3 −5 test/compilation/CompilationTestBase.sol
+81 −0 test/fixtures/config.toml
+0 −441 test/mocks/MockERC20.t.sol
+0 −721 test/mocks/MockERC721.t.sol
Loading
Loading