PUSD (Push USD) is a pegged USD stablecoin designed to pool liquidity from USDT and USDC across all chains and honor redeems. This repository contains the smart contract implementation for the PUSD token on Push Chain.
PUSD is an upgradeable ERC-20 token with the following features:
- Upgradeable: Built using OpenZeppelin's UUPS proxy pattern
- Access Control: Role-based permissions for minting, burning, and upgrading
- 6 Decimals: Matches USDT and USDC standard
- Protocol-Controlled: Mint and burn functions restricted to authorized protocol addresses
The contract uses:
- UUPS Proxy Pattern: For upgradeability without changing the proxy address
- Access Control: Three main roles:
MINTER_ROLE: Can mint new PUSD tokensBURNER_ROLE: Can burn PUSD tokensUPGRADER_ROLE: Can upgrade the implementation contractDEFAULT_ADMIN_ROLE: Can manage all roles
- Foundry
- Git
curl -L https://foundry.paradigm.xyz | bash
foundryupgit clone <repository-url>
cd push-chain-pusdforge install OpenZeppelin/openzeppelin-contracts
forge install OpenZeppelin/openzeppelin-contracts-upgradeable
forge install foundry-rs/forge-stdforge buildRun the test suite:
forge testRun tests with verbosity:
forge test -vvvRun tests with gas reporting:
forge test --gas-reportCopy the example environment file:
cp .env.example .envEdit .env and set your admin address:
ADMIN_ADDRESS=0xYourAdminAddress
Following best security practices, use Foundry's wallet management:
cast wallet import deployer --interactiveYou'll be prompted to enter your private key and create a password to encrypt it.
Ensure you have testnet tokens from the Push Chain faucet.
forge script script/DeployPUSD.s.sol:DeployPUSD \
--rpc-url push_testnet \
--chain 42101 \
--account deployer \
--broadcastVerify the implementation contract:
forge verify-contract \
--chain 42101 \
--verifier blockscout \
<IMPLEMENTATION_ADDRESS> \
src/PUSD.sol:PUSDVerify the proxy contract:
forge verify-contract \
--chain 42101 \
--verifier blockscout \
<PROXY_ADDRESS> \
@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol:ERC1967Proxycast send <PROXY_ADDRESS> \
"mint(address,uint256)" \
<RECIPIENT_ADDRESS> \
<AMOUNT> \
--rpc-url push_testnet \
--account deployercast send <PROXY_ADDRESS> \
"burn(address,uint256)" \
<FROM_ADDRESS> \
<AMOUNT> \
--rpc-url push_testnet \
--account deployercast send <PROXY_ADDRESS> \
"grantRole(bytes32,address)" \
$(cast keccak "MINTER_ROLE") \
<NEW_MINTER_ADDRESS> \
--rpc-url push_testnet \
--account deployercast call <PROXY_ADDRESS> \
"balanceOf(address)(uint256)" \
<ADDRESS> \
--rpc-url push_testnetTo upgrade the contract:
- Deploy new implementation:
// Create new implementation contract (e.g., PUSDv2.sol)
forge create src/PUSDv2.sol:PUSDv2 \
--rpc-url push_testnet \
--account deployer- Upgrade the proxy:
cast send <PROXY_ADDRESS> \
"upgradeToAndCall(address,bytes)" \
<NEW_IMPLEMENTATION_ADDRESS> \
0x \
--rpc-url push_testnet \
--account deployer- Never commit private keys or
.envfiles - Use hardware wallets or secure key management for mainnet deployments
- Always test upgrades on testnet first
- Ensure proper role management and access control
- Consider multi-sig for admin roles in production
push-chain-pusd/
├── src/
│ └── PUSD.sol # Main PUSD contract
├── script/
│ └── DeployPUSD.s.sol # Deployment script
├── test/
│ └── PUSD.t.sol # Test suite
├── foundry.toml # Foundry configuration
├── remappings.txt # Import remappings
└── README.md # This file
- Implement liquidity pooling mechanism for USDT/USDC
- Add cross-chain bridge integration
- Implement redemption logic
- Add pause/unpause functionality for emergency situations
- Implement rate limiting for mints/burns
- Add comprehensive event logging for off-chain tracking
MIT