USDat is a compliance-enabled extension token built on M (by M^0). Users deposit/withdraw through the M0 SwapFacility to wrap M (and JMI-allowed assets) into USDat; yield generated by the underlying M is routed to a configured yield recipient. On top of the base M-extension behaviour, USDat adds:
- Whitelist gating — when enabled, deposits, withdrawals and transfers are
restricted to whitelisted accounts (managed via
WHITELIST_MANAGER_ROLE). - Compliance controls — account freezing and forced transfers
(
ForcedTransferable) for regulatory requirements. - Pausing & role-based access control inherited from the M-extension base.
The contract is built with Foundry and Solidity
0.8.26.
USDat is deployed behind a transparent upgradeable proxy:
| Contract | Role |
|---|---|
| Proxy | User-facing address. Holds all state and funds. Deployed deterministically via CREATE3 (CreateX). |
| Implementation | src/USDat.sol — the audited logic. Stateless aside from immutables. |
| ProxyAdmin | Controls implementation upgrades; owned by the admin. |
USDat extends JMIExtension and ForcedTransferable from
m-extensions. Its constructor takes two immutables
baked into the bytecode — the M token and the SwapFacility — while operational
parameters (admin, compliance, processor, yield recipient) are set at
initialize() time and live in proxy storage.
USDat is IUSDat, JMIExtension, ForcedTransferable
├─ immutables : M_TOKEN, SWAP_FACILITY (constructor → bytecode)
└─ init params: yieldRecipient, admin, compliance, processor (proxy storage)
src/
USDat.sol # implementation (logic)
IUSDat.sol # public interface
script/
USDat.s.sol # DeployUSDat — deploys impl + proxy + ProxyAdmin
UpgradeUSDat.s.sol # implementation upgrade
VerifyCodeHash.s.sol # code-consistency proof helper (see below)
README.md # deployment details & addresses
test/ # Foundry tests
lib/ # dependencies (forge-std, m-extensions, OZ-upgradeable, solady)
verify.sh # one-command on-chain code verification
Requires Foundry.
forge build # compile
forge test # run tests
forge fmt # format
forge snapshot # gas snapshotsBuild settings (see foundry.toml): solc 0.8.26, optimizer enabled (200
runs), via_ir = true.
See script/README.md for full deployment details. In
short, the proxy is deployed deterministically via the
CreateX factory
(0xba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed) with salt "USDat", so it
resolves to the same address on every chain for a given deployer.
source .env && forge script script/USDat.s.sol:DeployUSDat \
--rpc-url $RPC_URL --broadcastSupply a signer via your preferred Foundry method (e.g. --account <keystore>
or a hardware wallet flag).
Required environment variables: RPC_URL, M_TOKEN, SWAP_FACILITY, ADMIN,
COMPLIANCE, PROCESSOR, YIELD_RECIPIENT.
| Item | Address |
|---|---|
| Proxy (user-facing) | 0x23238f20b894f29041f48D88eE91131C395Aaa71 |
| Implementation | 0x17cac25c6d6bbcb592837fea083a5c8eb4d1e52e |
M_TOKEN (immutable) |
0x866A2BF4E572CbcF37D5071A7a58503Bfb36be1b |
SWAP_FACILITY (immutable) |
0xB6807116b3B1B321a390594e31ECD6e0076f6278 |
The implementation was audited at commit
8735152da4d5182f34cf29771757737d33894064. The script below proves — with a
single hash on each side — that the code deployed on mainnet is exactly the
audited source.
Compile the source at the audited commit, deploy it in a local EVM with the production constructor arguments, and confirm the resulting runtime code hash equals the code hash of the live mainnet implementation.
bash verify.sh # reads RPC_URL, M_TOKEN, SWAP_FACILITY from .env.productionNo checkout required: verify.sh first runs a read-only git diff to confirm
the source in your tree is byte-identical to the audited commit, then builds and
compares. (It does not move your checkout or modify the repo.)
Expected output:
network : Ethereum mainnet (chain id 1)
implementation : 0x17cac25c6d6bbcb592837fea083a5c8eb4d1e52e
audited commit : 8735152da4d5182f34cf29771757737d33894064 (source verified identical)
local code hash : 0x5cc574845a8fd858923a985ab3c6417713aa473b0aafe6c8e0081a101bf2bb68
production code hash : 0x5cc574845a8fd858923a985ab3c6417713aa473b0aafe6c8e0081a101bf2bb68
MATCH - mainnet 0x17cac25c6d6bbcb592837fea083a5c8eb4d1e52e runs the audited code (commit 8735152da4d5182f34cf29771757737d33894064)
| Item | Value |
|---|---|
| Audited commit | 8735152da4d5182f34cf29771757737d33894064 |
| Implementation | 0x17cac25c6d6bbcb592837fea083a5c8eb4d1e52e (mainnet) |
Runtime code hash (EXTCODEHASH) |
0x5cc574845a8fd858923a985ab3c6417713aa473b0aafe6c8e0081a101bf2bb68 |
| Metadata IPFS hash (embedded in bytecode) | 45472ce17e1ff7ff1ddeb6da763cf1f2d545305b71f993a3304b5d68bdd6ce45 |
script/VerifyCodeHash.s.soldeploysUSDat(M_TOKEN, SWAP_FACILITY)in a local EVM and printsaddress(impl).codehash. The local deploy links the two immutables exactly as mainnet did, so the hash is directly comparable to the on-chainEXTCODEHASH— no byte-diffing or immutable handling required.verify.shconfirms — with a read-onlygit diff— that the source here is identical to the audited commit, gets that local hash, fetches the production hash viacast codehash, and asserts the two hashes match. No checkout or other state-changing git command is used.
The runtime code hash is fully determined by (audited source + compiler settings + the two immutable addresses). A match therefore proves the deployed implementation bytecode is the audited code built from this commit with these arguments. As an independent cross-check, the metadata IPFS hash Solidity embeds in the bytecode (a fingerprint of the source files + compiler settings) is identical in the local build and on-chain.
Scope: this verifies the implementation logic. The operational parameters
set at initialize() (ADMIN, COMPLIANCE, PROCESSOR, YIELD_RECIPIENT)
are proxy storage state, not part of the implementation bytecode, and are
verified separately by reading the proxy's roles/configuration.
Business Source License 1.1 (BUSL-1.1). See SPDX headers in src/.