The Treasury contract manages fund collection, distribution, and reserve management for building operations. It provides automated fund distribution between business operations and reserve management with governance-controlled payment processing.
The Treasury contract provides:
- Fund Collection: Accepts USDC deposits from various sources
- Automated Distribution: Splits funds between business and treasury
- Reserve Management: Maintains operational reserves
- Payment Processing: Governance-controlled payments
- Excess Fund Forwarding: Automatically forwards excess funds to vaults
- Automated Distribution: N% to business, M% to treasury
- Reserve Management: Maintains minimum reserve amounts
- Governance Control: Restricted payment capabilities
- Vault Integration: Forwards excess funds to yield-generating vaults
- Role-Based Access: Different roles for different operations
contract Treasury is AccessControlUpgradeable, TreasuryStorage, ITreasury {
// Roles
bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE");
bytes32 public constant FACTORY_ROLE = keccak256("FACTORY_ROLE");
// Treasury data
TreasuryData storage $ = _getTreasuryStorage();
}function deposit(uint256 amount) externalParameters:
amount: Amount of USDC to deposit
Process:
- Transfers USDC from caller
- Distributes funds according to N/M percentage split
- Forwards excess funds to vault
- Emits deposit event
function makePayment(address to, uint256 amount) external onlyRole(GOVERNANCE_ROLE)Parameters:
to: Recipient addressamount: Payment amount
Process:
- Validates recipient and amount
- Checks sufficient balance
- Transfers USDC to recipient
- Forwards excess funds to vault
function setReserveAmount(uint256 newReserveAmount) external onlyRole(GOVERNANCE_ROLE)Parameters:
newReserveAmount: New minimum reserve amount
Process:
- Validates new reserve amount
- Updates reserve configuration
- Forwards excess funds to vault
function addVault(address _vault) public onlyRole(FACTORY_ROLE)Parameters:
_vault: Vault address for excess funds
Process:
- Validates vault address
- Sets vault for excess fund forwarding
- Enables automatic fund forwarding
function grantGovernanceRole(address governance) external onlyRole(FACTORY_ROLE)Parameters:
governance: Address to grant governance role
function grantFactoryRole(address factory) external onlyRole(DEFAULT_ADMIN_ROLE)Parameters:
factory: Address to grant factory role
The treasury automatically distributes incoming funds:
function _distributeFunds(uint256 amount) internal {
uint256 toBusiness = (amount * $.nPercentage) / 10000;
uint256 toTreasury = amount - toBusiness;
// N% to business
IERC20($.usdc).safeTransfer($.businessAddress, toBusiness);
// M% remains in treasury
// Excess funds forwarded to vault
}The treasury maintains a minimum reserve amount:
function _forwardExcessFunds() internal {
uint256 balance = IERC20($.usdc).balanceOf(address(this));
if (balance > $.reserveAmount) {
uint256 excessAmount = balance - $.reserveAmount;
// Forward excess to vault
IRewards($.vault).addReward($.usdc, excessAmount);
}
}function initialize(
address _usdcAddress,
uint256 _reserveAmount,
uint256 _nPercentage,
address _initialOwner,
address _businessAddress,
address _buildingFactory
) public initializerParameters:
_usdcAddress: USDC token address_reserveAmount: Minimum reserve amount_nPercentage: Business percentage (in basis points)_initialOwner: Initial owner address_businessAddress: Business address for payments_buildingFactory: Building factory address
// Deploy Treasury
const treasury = await ethers.deployContract("Treasury");
// Initialize Treasury
await treasury.initialize(
usdcAddress,
ethers.parseUnits("10000", 6), // 10,000 USDC reserve
2000, // 20% to business
deployerAddress,
businessAddress,
buildingFactoryAddress,
);
console.log("Treasury deployed to:", treasury.target);- Governance Role: Payment processing and configuration
- Factory Role: Vault management and role assignment
- Admin Role: Initial setup and role management
- Public: Fund deposits only
- Reserve Management: Maintains minimum reserves
- Excess Forwarding: Automatically forwards excess to vaults
- Payment Validation: Validates all payments
- Balance Checks: Ensures sufficient funds
- Upgradeable Contract: Uses OpenZeppelin upgradeable contracts
- Storage Separation: Uses separate storage contract
- Initialization: Proper initialization pattern
The Treasury includes comprehensive tests:
- Fund deposit and distribution
- Payment processing
- Reserve management
- Role management
- Vault integration
- Edge cases and error conditions
# Run treasury tests
yarn hardhat test test/treasury/treasury.test.ts
# Run with gas reporting
yarn hardhat test test/treasury/treasury.test.ts --gas-report// Connect to Treasury
const treasury = await ethers.getContractAt("Treasury", treasuryAddress);
// Deposit funds
await treasury.deposit(ethers.parseUnits("10000", 6)); // 10,000 USDC
// Check treasury balance
const balance = await treasury.getBalance();
// Check reserve amount
const reserve = await treasury.reserve();// Make payment (governance only)
await treasury.makePayment(
recipientAddress,
ethers.parseUnits("5000", 6), // 5,000 USDC
);
// Update reserve amount
await treasury.setReserveAmount(
ethers.parseUnits("15000", 6), // 15,000 USDC
);// Add vault for excess funds
await treasury.addVault(vaultAddress);
// Check vault address
const vault = await treasury.vault();// Grant governance role
await treasury.grantGovernanceRole(governanceAddress);
// Grant factory role
await treasury.grantFactoryRole(factoryAddress);The Treasury integrates with building contracts to:
- Fund Collection: Receive building-related payments
- Payment Processing: Make building-related payments
- Reserve Management: Maintain building reserves
- Vault Integration: Forward excess funds to building vaults
The Treasury integrates with vault contracts to:
- Excess Fund Forwarding: Automatically forward excess funds
- Reward Distribution: Add rewards to vaults
- Yield Generation: Generate yield on excess funds
- Balance Management: Maintain optimal fund levels
The Treasury integrates with governance contracts to:
- Payment Authorization: Governance-controlled payments
- Configuration Updates: Governance-controlled settings
- Role Management: Governance-controlled access
- Emergency Functions: Governance-controlled emergency actions
- Batch Operations: No batch operations currently implemented
- Storage Optimization: Efficient data structures
- Event Optimization: Minimal event data
- Gas Estimation: Pre-calculate gas costs
- Automatic Distribution: Efficient fund splitting
- Excess Forwarding: Automatic vault integration
- Reserve Management: Efficient reserve calculations
- Payment Processing: Optimized payment logic
error Treasury: Invalid USDC address
error Treasury: Invalid governance address
error Treasury: Invalid N percentage
error Treasury: Reserve amount must be greater than zero- Invalid USDC address
- Invalid governance address
- Invalid N percentage (must be β€ 10000)
- Reserve amount must be greater than zero
- Insufficient funds for payments
- Invalid recipient addresses
The Treasury is upgradeable using OpenZeppelin upgradeable contracts:
- Deploy New Implementation: Deploy new implementation contract
- Update Proxy: Update proxy to point to new implementation
- Data Migration: Migrate existing data if necessary
- Validation: Verify upgrade success
- Treasury Balance: Total USDC balance
- Reserve Amount: Minimum reserve maintained
- Business Payments: Total payments to business
- Excess Forwarding: Funds forwarded to vaults
// Fund events
event Deposit(address indexed user, uint256 amount);
event FundsDistributed(uint256 toBusiness, uint256 toTreasury);
event ExcessFundsForwarded(uint256 amount);
// Payment events
event Payment(address indexed recipient, uint256 amount);
// Configuration events
event ReserveAmountUpdated(uint256 newAmount);
event VaultAdded(address indexed vault);For questions or issues related to the Treasury:
- Check the test files for usage examples
- Review the contract source code
- Open an issue in the repository
- Contact the development team
Next Steps: