Skip to main content

Foundry Configuration

The project uses Foundry with:
  • Solidity: 0.8.24
  • EVM target: Cancun
  • Optimizer: 200 runs
  • Dependencies: OpenZeppelin v5.5.0 (contracts + upgradeable)
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.24"
evm_version = "cancun"
optimizer = true
optimizer_runs = 200

remappings = [
  "forge-std/=lib/forge-std/src/",
  "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
  "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
]

Etherscan Verification

[etherscan]
base_sepolia = { key = "${ETHERSCAN_API_KEY}", url = "https://api-sepolia.basescan.org/api" }
base_mainnet = { key = "${ETHERSCAN_API_KEY}", url = "https://api.basescan.org/api" }

Deployment Scripts

V1: Intent Settlers (script/Deploy.s.sol)

Deploys the original intent settlement suite.
1

Deploy IntentRegistry

No constructor arguments. Deployed as a standalone contract.
2

Deploy PodiumOriginSettler

Constructor: PodiumOriginSettler(address registry)
3

Deploy PodiumDestinationSettler

Constructor: PodiumDestinationSettler(address originSettler, address registry)
4

Wire references

registry.setOriginSettler(address(originSettler));
originSettler.setDestinationSettler(address(destinationSettler));
5

Deploy MockUSDC (testnet only)

On non-mainnet chains (chainId != 8453), deploys a MockUSDC for testing.
forge script script/Deploy.s.sol \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --broadcast \
  --verify \
  --etherscan-api-key $ETHERSCAN_API_KEY

V2: Task Pool System (script/DeployV2.s.sol)

Deploys the full multi-tenant system with proxy patterns.
1

USDC

Testnet: deploys MockUSDC. Mainnet: uses canonical address 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913.
2

SolverRegistry

Deploy implementation + ERC1967Proxy.
SolverRegistry solverImpl = new SolverRegistry();
ERC1967Proxy solverProxy = new ERC1967Proxy(
    address(solverImpl),
    abi.encodeCall(SolverRegistry.initialize, (deployer))
);
3

VerificationEngine

Deploy implementation + ERC1967Proxy.
VerificationEngine veImpl = new VerificationEngine();
ERC1967Proxy veProxy = new ERC1967Proxy(
    address(veImpl),
    abi.encodeCall(VerificationEngine.initialize, (deployer, oracleAddress))
);
oracleAddress defaults to deployer if AI_ORACLE_ADDRESS is not set.
4

IntentRegistryV2

Deploy implementation + ERC1967Proxy.
IntentRegistryV2 irImpl = new IntentRegistryV2();
ERC1967Proxy irProxy = new ERC1967Proxy(
    address(irImpl),
    abi.encodeCall(IntentRegistryV2.initialize, (deployer))
);
5

Pool Implementations

Deploy bare implementations (no proxy — these are used as Beacon targets):
TaskPoolImplementation taskPoolImpl = new TaskPoolImplementation();
RewardPoolImplementation rewardPoolImpl = new RewardPoolImplementation();
6

TaskPoolFactory

Deploy factory, which internally creates UpgradeableBeacons for both pool types:
TaskPoolFactory factory = new TaskPoolFactory(
    address(taskPoolImpl),
    address(rewardPoolImpl),
    address(solverRegistry),
    address(verificationEngine),
    address(intentRegistry),
    address(usdc)
);
7

Authorize factory

intentRegistry.addAuthorizedCaller(address(factory));
8

Transfer ownership (optional)

If SAFE_MULTISIG_ADDRESS is set:
solverRegistry.transferOwnership(SAFE_MULTISIG_ADDRESS);
verificationEngine.transferOwnership(SAFE_MULTISIG_ADDRESS);
intentRegistry.transferOwnership(SAFE_MULTISIG_ADDRESS);
factory.transferOwnership(SAFE_MULTISIG_ADDRESS);
forge script script/DeployV2.s.sol \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --broadcast \
  --verify \
  --etherscan-api-key $ETHERSCAN_API_KEY

Output

The deploy script logs all addresses:
USDC_ADDRESS=0x...
TASK_POOL_FACTORY_ADDRESS=0x...
SOLVER_REGISTRY_ADDRESS=0x...
VERIFICATION_ENGINE_ADDRESS=0x...
INTENT_REGISTRY_ADDRESS=0x...
Save these to your .env for the Podium API server.

Upgrade: Beacon Implementations (script/Upgrade.s.sol)

Upgrades TaskPool and/or RewardPool beacon implementations. All existing tenant pools are upgraded atomically via the beacon pattern.
UPGRADE_TASK_POOL=true UPGRADE_REWARD_POOL=true \
  forge script script/Upgrade.s.sol \
  --rpc-url $BASE_SEPOLIA_RPC_URL \
  --broadcast
The upgrade script:
  1. Deploys new implementation contract(s)
  2. Calls factory.upgradeTaskPool(newImpl) and/or factory.upgradeRewardPool(newImpl)
  3. All beacon proxies immediately point to the new implementation

Supported Networks

NetworkChain IDUSDC AddressPurpose
Base Mainnet84530x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Production
Base Sepolia84532MockUSDC (deployed per environment)Testnet
Arc Testnet16374500x3600000000000000000000000000000000000000Development

Base Mainnet (Production)

  • Chain ID: 8453
  • RPC: Set via BASE_MAINNET_RPC_URL
  • Block explorer: basescan.org
  • USDC: Circle’s canonical deployment
  • Gas token: ETH

Base Sepolia (Testnet)

  • Chain ID: 84532
  • RPC: Set via BASE_SEPOLIA_RPC_URL
  • Block explorer: sepolia.basescan.org
  • USDC: MockUSDC deployed by the deploy script
  • Gas token: Sepolia ETH (free from faucets)

Arc Testnet (Development)

  • USDC is the native gas token (no separate ERC-20)
  • USDC address: 0x3600000000000000000000000000000000000000
  • Circle SDK targets ARC-TESTNET blockchain identifier

Environment Variables

# Deployer
DEPLOYER_PRIVATE_KEY=0x...

# Network RPC
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org
BASE_MAINNET_RPC_URL=https://mainnet.base.org

# Verification
ETHERSCAN_API_KEY=your_basescan_api_key

# V2 Deployment
AI_ORACLE_ADDRESS=0x...           # VerificationEngine oracle (defaults to deployer)
SAFE_MULTISIG_ADDRESS=0x...       # Optional: transfer ownership to multisig

# Upgrade
UPGRADE_TASK_POOL=true|false
UPGRADE_REWARD_POOL=true|false
TASK_POOL_FACTORY_ADDRESS=0x...   # Required for upgrades

Contract Verification

After deployment, verify contracts on Basescan:
forge verify-contract \
  --chain-id 84532 \
  --constructor-args $(cast abi-encode "constructor(address)" 0xRegistryAddr) \
  0xDeployedAddr \
  src/PodiumOriginSettler.sol:PodiumOriginSettler \
  --etherscan-api-key $ETHERSCAN_API_KEY
For proxy contracts (V2), verify both the implementation and the proxy:
forge verify-contract \
  --chain-id 84532 \
  0xImplementationAddr \
  src/SolverRegistry.sol:SolverRegistry \
  --etherscan-api-key $ETHERSCAN_API_KEY

forge verify-contract \
  --chain-id 84532 \
  0xProxyAddr \
  lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol:ERC1967Proxy \
  --etherscan-api-key $ETHERSCAN_API_KEY

Mainnet Deployment Checklist

1

Audit

Ensure all contracts have been audited. Review any changes since the last audit.
2

Test on Sepolia

Deploy to Base Sepolia first. Run the full test suite against the testnet deployment.
forge test --fork-url $BASE_SEPOLIA_RPC_URL
3

Prepare multisig

Set up a Gnosis Safe multisig on Base Mainnet for ownership. At least 3 signers with 2/3 threshold recommended.
4

Deploy

SAFE_MULTISIG_ADDRESS=0xYourSafe... \
forge script script/DeployV2.s.sol \
  --rpc-url $BASE_MAINNET_RPC_URL \
  --broadcast \
  --verify
5

Verify on Basescan

Verify all deployed contracts on Basescan for transparency.
6

Configure Podium API

Update the Podium API server environment with the new contract addresses.
7

Test tenant pool creation

Create a test tenant pool via the API to verify the full flow works end-to-end.
8

Transfer ownership

If not done during deployment, transfer ownership of all V2 contracts to the multisig:
solverRegistry.transferOwnership(SAFE_MULTISIG_ADDRESS);
verificationEngine.transferOwnership(SAFE_MULTISIG_ADDRESS);
intentRegistry.transferOwnership(SAFE_MULTISIG_ADDRESS);
factory.transferOwnership(SAFE_MULTISIG_ADDRESS);

Circle SDK Integration

The circle-sdk/ directory provides a Node.js/TypeScript integration layer using Circle’s Dev-Controlled Wallets and Smart Contract Platform SDKs, targeting Arc Testnet.

Available Scripts

ScriptPurpose
generate-entity-secret.tsGenerate Circle entity secret
register-entity-secret.tsRegister with Circle
create-wallet.tsCreate dev-controlled wallet
wallet-balance.tsCheck wallet balance
deploy-erc20.tsDeploy ERC-20 template on Arc
deploy-erc721.tsDeploy ERC-721 template
deploy-erc1155.tsDeploy ERC-1155 template
deploy-airdrop.tsDeploy airdrop template
transfer-usdc.tsTransfer USDC between wallets

Arc Testnet Notes

  • Arc Testnet uses USDC as the native gas token
  • USDC address on Arc: 0x3600000000000000000000000000000000000000
  • Circle SDK targets ARC-TESTNET blockchain identifier

Shell Utility Scripts

ScriptPurpose
deploy-hello-arc.shDeploy HelloArchitect contract to Arc Testnet
call-greeting.shRead greeting via cast call
verify-deploy.shVerify deployment matches expected state
print-env-checklist.shCheck required env vars
funding-check.shCheck native balance