Deployment Protocol
WIA-FIN-007 Phase 3 defines standardized deployment procedures ensuring consistent, secure, and verifiable contract deployment across all supported blockchains.
CREATE2 Deterministic Deployment
// WIA Standard Deployment using CREATE2
import { WIADeployer } from '@wia/deployer';
import { ethers } from 'ethers';
const deployer = new WIADeployer({
privateKey: process.env.DEPLOYER_PRIVATE_KEY,
rpcUrls: {
ethereum: 'https://eth.llamarpc.com',
polygon: 'https://polygon.llamarpc.com',
arbitrum: 'https://arb1.arbitrum.io/rpc'
}
});
// Compute deterministic address before deployment
const salt = ethers.utils.id('WIA-SecureToken-v1.0.0');
const predictedAddress = await deployer.computeAddress({
bytecode: contractBytecode,
salt: salt,
deployer: deployerAddress
});
console.log('Contract will be deployed to:', predictedAddress);
// Deploy to multiple chains with same address
const deployment = await deployer.deployDeterministic({
contract: 'WIASecureToken',
bytecode: contractBytecode,
constructorArgs: [],
salt: salt,
chains: ['ethereum', 'polygon', 'arbitrum'],
initializeData: {
name: 'WIA Token',
symbol: 'WIA',
decimals: 18,
initialSupply: ethers.utils.parseEther('1000000')
}
});
// Verify all deployments
console.log('Ethereum:', deployment.addresses.ethereum);
console.log('Polygon:', deployment.addresses.polygon);
console.log('Arbitrum:', deployment.addresses.arbitrum);
console.log('All addresses match:', deployment.allAddressesMatch); // true
Deployment Checklist
// Pre-deployment validation
const preDeployChecklist = await deployer.validatePreDeployment({
contract: 'WIASecureToken',
bytecode: contractBytecode,
chains: ['ethereum', 'polygon']
});
console.log('Checklist:');
console.log('โ Bytecode size < 24KB:', preDeployChecklist.bytecodeSizeValid);
console.log('โ Constructor args valid:', preDeployChecklist.constructorArgsValid);
console.log('โ Sufficient deployer balance:', preDeployChecklist.sufficientBalance);
console.log('โ No existing deployment:', preDeployChecklist.addressAvailable);
console.log('โ Security audit completed:', preDeployChecklist.auditCompleted);
if (!preDeployChecklist.allValid) {
throw new Error('Pre-deployment validation failed');
}
// Deploy with comprehensive logging
const deployment = await deployer.deploy({
contract: 'WIASecureToken',
onStepComplete: (step) => {
console.log(\`โ \${step.name} completed on \${step.chain}\`);
console.log(\` Tx hash: \${step.txHash}\`);
console.log(\` Gas used: \${step.gasUsed}\`);
},
onError: (error, chain) => {
console.error(\`โ Deployment failed on \${chain}: \${error.message}\`);
}
});
Upgrade Mechanisms
Transparent Proxy Pattern
// WIA Transparent Proxy Implementation
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import "@openzeppelin/contracts/proxy/transparent/ProxyAdmin.sol";
contract WIAProxy is TransparentUpgradeableProxy {
constructor(
address _logic,
address admin_,
bytes memory _data
) TransparentUpgradeableProxy(_logic, admin_, _data) {}
}
contract WIAProxyAdmin is ProxyAdmin {
// 48-hour timelock for upgrades
uint256 public constant UPGRADE_DELAY = 48 hours;
mapping(bytes32 => uint256) public upgradeTimelocks;
mapping(bytes32 => bool) public upgradeCancelled;
event UpgradeProposed(
address indexed proxy,
address indexed newImplementation,
uint256 executeAfter
);
event UpgradeExecuted(
address indexed proxy,
address indexed newImplementation
);
event UpgradeCancelled(
address indexed proxy,
address indexed newImplementation
);
function proposeUpgrade(
address proxy,
address newImplementation
) external onlyOwner {
require(newImplementation != address(0), "Invalid implementation");
require(_isValidImplementation(newImplementation), "Invalid contract");
bytes32 upgradeId = keccak256(abi.encodePacked(proxy, newImplementation));
require(upgradeTimelocks[upgradeId] == 0, "Upgrade already proposed");
uint256 executeAfter = block.timestamp + UPGRADE_DELAY;
upgradeTimelocks[upgradeId] = executeAfter;
emit UpgradeProposed(proxy, newImplementation, executeAfter);
}
function executeUpgrade(
address proxy,
address newImplementation
) external onlyOwner {
bytes32 upgradeId = keccak256(abi.encodePacked(proxy, newImplementation));
require(upgradeTimelocks[upgradeId] != 0, "Upgrade not proposed");
require(block.timestamp >= upgradeTimelocks[upgradeId], "Timelock active");
require(!upgradeCancelled[upgradeId], "Upgrade cancelled");
// Execute upgrade
upgrade(ITransparentUpgradeableProxy(proxy), newImplementation);
delete upgradeTimelocks[upgradeId];
emit UpgradeExecuted(proxy, newImplementation);
}
function cancelUpgrade(
address proxy,
address newImplementation
) external onlyOwner {
bytes32 upgradeId = keccak256(abi.encodePacked(proxy, newImplementation));
require(upgradeTimelocks[upgradeId] != 0, "Upgrade not proposed");
upgradeCancelled[upgradeId] = true;
delete upgradeTimelocks[upgradeId];
emit UpgradeCancelled(proxy, newImplementation);
}
function _isValidImplementation(address implementation) internal view returns (bool) {
// Verify implementation has required interface
uint256 size;
assembly { size := extcodesize(implementation) }
return size > 0;
}
}
UUPS Proxy Pattern
// WIA UUPS Implementation
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
contract WIASecureTokenUUPS is UUPSUpgradeable, Ownable2StepUpgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
function initialize(
string memory name,
string memory symbol,
uint256 initialSupply
) public initializer {
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
// Initialize token state
_name = name;
_symbol = symbol;
_mint(msg.sender, initialSupply);
}
function _authorizeUpgrade(address newImplementation)
internal
override
onlyOwner
{
require(_isValidUpgrade(newImplementation), "Invalid upgrade");
}
function _isValidUpgrade(address newImplementation) internal view returns (bool) {
// Verify storage layout compatibility
// Verify required functions exist
// Verify security checks
return true; // Implement actual validation
}
// Storage layout validation
function getStorageLayout() public pure returns (bytes32) {
return keccak256("WIASecureToken.storage.v1");
}
}
Security Verification
Formal Verification Integration
// WIA Security Verification Protocol
import { WIAVerifier } from '@wia/security';
const verifier = new WIAVerifier();
// Static analysis
const staticAnalysis = await verifier.runStaticAnalysis({
contract: 'WIASecureToken',
tools: ['slither', 'mythril', 'securify']
});
console.log('Vulnerabilities found:', staticAnalysis.vulnerabilities.length);
staticAnalysis.vulnerabilities.forEach(vuln => {
console.log(\`- \${vuln.severity}: \${vuln.description}\`);
});
// Formal verification
const formalVerification = await verifier.runFormalVerification({
contract: 'WIASecureToken',
properties: [
'no-reentrancy',
'no-overflow',
'access-control',
'state-consistency'
]
});
console.log('Formal verification passed:', formalVerification.passed);
// Symbolic execution
const symbolicExecution = await verifier.runSymbolicExecution({
contract: 'WIASecureToken',
functions: ['transfer', 'transferFrom', 'approve']
});
console.log('Execution paths analyzed:', symbolicExecution.pathsAnalyzed);
console.log('Violations found:', symbolicExecution.violations.length);
Runtime Monitoring
// On-chain monitoring contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract WIASecurityMonitor {
struct SecurityEvent {
address contractAddress;
string eventType;
bytes data;
uint256 timestamp;
uint256 blockNumber;
}
mapping(address => SecurityEvent[]) public events;
mapping(address => bool) public suspicious;
event SecurityAlert(
address indexed contractAddress,
string alertType,
uint256 severity,
bytes data
);
// Monitor unusual activity
function reportSuspiciousActivity(
address contractAddress,
string memory activityType,
bytes memory evidence
) external {
SecurityEvent memory evt = SecurityEvent({
contractAddress: contractAddress,
eventType: activityType,
data: evidence,
timestamp: block.timestamp,
blockNumber: block.number
});
events[contractAddress].push(evt);
if (_isCritical(activityType)) {
suspicious[contractAddress] = true;
emit SecurityAlert(contractAddress, activityType, 3, evidence);
}
}
function _isCritical(string memory activityType) internal pure returns (bool) {
return keccak256(bytes(activityType)) == keccak256("REENTRANCY_DETECTED") ||
keccak256(bytes(activityType)) == keccak256("UNAUTHORIZED_ACCESS");
}
}
Multi-Signature Governance
WIA Multisig Implementation
// WIA Multi-Signature Wallet for Contract Governance
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract WIAMultisig {
uint256 public constant TRANSACTION_EXPIRY = 7 days;
address[] public owners;
mapping(address => bool) public isOwner;
uint256 public requiredSignatures;
struct Transaction {
address to;
uint256 value;
bytes data;
bool executed;
uint256 expiresAt;
mapping(address => bool) signatures;
uint256 signatureCount;
}
mapping(uint256 => Transaction) public transactions;
uint256 public transactionCount;
event TransactionProposed(
uint256 indexed txId,
address indexed proposer,
address to,
bytes data
);
event TransactionSigned(uint256 indexed txId, address indexed signer);
event TransactionExecuted(uint256 indexed txId);
event TransactionExpired(uint256 indexed txId);
modifier onlyOwner() {
require(isOwner[msg.sender], "Not owner");
_;
}
constructor(address[] memory _owners, uint256 _requiredSignatures) {
require(_owners.length >= _requiredSignatures, "Invalid setup");
require(_requiredSignatures > 0, "Need signatures");
for (uint i = 0; i < _owners.length; i++) {
require(_owners[i] != address(0), "Invalid owner");
require(!isOwner[_owners[i]], "Duplicate owner");
owners.push(_owners[i]);
isOwner[_owners[i]] = true;
}
requiredSignatures = _requiredSignatures;
}
function proposeTransaction(
address to,
uint256 value,
bytes memory data
) external onlyOwner returns (uint256) {
uint256 txId = transactionCount++;
Transaction storage txn = transactions[txId];
txn.to = to;
txn.value = value;
txn.data = data;
txn.expiresAt = block.timestamp + TRANSACTION_EXPIRY;
emit TransactionProposed(txId, msg.sender, to, data);
// Auto-sign by proposer
signTransaction(txId);
return txId;
}
function signTransaction(uint256 txId) public onlyOwner {
Transaction storage txn = transactions[txId];
require(!txn.executed, "Already executed");
require(block.timestamp < txn.expiresAt, "Transaction expired");
require(!txn.signatures[msg.sender], "Already signed");
txn.signatures[msg.sender] = true;
txn.signatureCount++;
emit TransactionSigned(txId, msg.sender);
if (txn.signatureCount >= requiredSignatures) {
executeTransaction(txId);
}
}
function executeTransaction(uint256 txId) internal {
Transaction storage txn = transactions[txId];
require(!txn.executed, "Already executed");
require(txn.signatureCount >= requiredSignatures, "Need more signatures");
txn.executed = true;
(bool success, ) = txn.to.call{value: txn.value}(txn.data);
require(success, "Transaction failed");
emit TransactionExecuted(txId);
}
}
Chain Compatibility
EVM Compatibility Testing
// WIA Chain Compatibility Verification
import { WIACompatibilityTester } from '@wia/testing';
const tester = new WIACompatibilityTester();
const compatibilityReport = await tester.testChainCompatibility({
contract: 'WIASecureToken',
chains: [
'ethereum',
'polygon',
'arbitrum',
'optimism',
'avalanche',
'bsc'
],
tests: [
'deployment',
'basic-operations',
'gas-costs',
'event-emission',
'edge-cases',
'security'
]
});
// Check results
compatibilityReport.chains.forEach(chain => {
console.log(\`\${chain.name}: \${chain.compatible ? 'โ' : 'โ'}\`);
console.log(\` Gas costs: \${chain.gasCosts.transfer} (transfer)\`);
console.log(\` All tests passed: \${chain.allTestsPassed}\`);
if (!chain.compatible) {
console.log(\` Issues: \${chain.issues.join(', ')}\`);
}
});
Emergency Procedures
Circuit Breaker Pattern
// WIA Emergency Stop Mechanism
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
contract WIACircuitBreaker is Pausable, AccessControl {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
bytes32 public constant UNPAUSER_ROLE = keccak256("UNPAUSER_ROLE");
uint256 public constant MIN_PAUSE_DURATION = 1 hours;
uint256 public constant MAX_PAUSE_DURATION = 30 days;
uint256 public pausedAt;
uint256 public pauseDuration;
string public pauseReason;
event EmergencyStop(
address indexed triggeredBy,
string reason,
uint256 duration,
uint256 timestamp
);
event EmergencyResume(
address indexed triggeredBy,
uint256 pausedFor,
uint256 timestamp
);
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(PAUSER_ROLE, msg.sender);
_grantRole(UNPAUSER_ROLE, msg.sender);
}
function emergencyStop(
string memory reason,
uint256 duration
) external onlyRole(PAUSER_ROLE) {
require(!paused(), "Already paused");
require(duration >= MIN_PAUSE_DURATION, "Duration too short");
require(duration <= MAX_PAUSE_DURATION, "Duration too long");
pausedAt = block.timestamp;
pauseDuration = duration;
pauseReason = reason;
_pause();
emit EmergencyStop(msg.sender, reason, duration, block.timestamp);
}
function emergencyResume() external onlyRole(UNPAUSER_ROLE) {
require(paused(), "Not paused");
require(
block.timestamp >= pausedAt + MIN_PAUSE_DURATION,
"Minimum pause duration not met"
);
uint256 pausedFor = block.timestamp - pausedAt;
_unpause();
emit EmergencyResume(msg.sender, pausedFor, block.timestamp);
// Clear pause data
delete pausedAt;
delete pauseDuration;
delete pauseReason;
}
function canResume() public view returns (bool) {
return paused() && block.timestamp >= pausedAt + MIN_PAUSE_DURATION;
}
}
Phase 3 Best Practices
- Always use CREATE2 for deterministic multi-chain deployments
- Implement timelock delays for all upgrade operations
- Run comprehensive security verification before deployment
- Use multi-signature governance for critical functions
- Test compatibility across all target chains
- Implement emergency stop mechanisms
- Monitor contracts continuously post-deployment
Phase 3 Protocol ensures secure deployment and upgrade procedures. Next, we'll explore Phase 4 Integration for connecting with the broader ecosystem.