Reward Distributor API Reference
Contract Interface
The RewardDistributor contract provides a secure interface for managing token distributions and executing privileged operations.
Core Functions
Token Management
function approveERC20(
address token,
address spender,
uint256 amount
) external onlyOwner whenNotPaused
Approves token spending for a specified spender.
- Parameters:
token: Address of the ERC20 tokenspender: Address approved to spend tokensamount: Amount of tokens to approve
- Access: Owner only
- State: Not paused
- Events: None (relies on ERC20 Approval event)
Token Withdrawal
function withdrawERC20(
address token,
address receiver,
uint256 amount
) external onlyOwner whenNotPaused
Withdraws tokens to a specified receiver.
- Parameters:
token: Address of the ERC20 tokenreceiver: Address to receive tokensamount: Amount of tokens to withdraw
- Access: Owner only
- State: Not paused
- Events: None (relies on ERC20 Transfer event)
Transaction Execution
function execTransaction(
address to,
uint256 value,
bytes calldata data
) external onlyOwner whenNotPaused
Executes an arbitrary transaction.
- Parameters:
to: Target contract addressvalue: ETH value to senddata: Transaction data
- Access: Owner only
- State: Not paused
- Events:
ExecTransaction - Returns: None
- Throws: If transaction fails
Security Controls
Pause Contract
function pause() external onlyOwner
Pauses all contract operations.
- Parameters: None
- Access: Owner only
- Events:
Paused - State Changes: Sets paused state to true
Unpause Contract
function unpause() external onlyOwner
Unpauses contract operations.
- Parameters: None
- Access: Owner only
- Events:
Unpaused - State Changes: Sets paused state to false
Events
event ExecTransaction(
address from,
address excutionContract,
uint256 value,
bytes data
)
Emitted when a transaction is executed.
- Parameters:
from: Transaction initiatorexcutionContract: Target contractvalue: ETH value sentdata: Transaction data
Usage Examples
Basic Token Management
- Token Approval
- Token Withdrawal
// Approve token spending
await distributor.approveERC20(
tokenAddress,
spenderAddress,
ethers.utils.parseEther("1000")
);
// Withdraw tokens
await distributor.withdrawERC20(
tokenAddress,
receiverAddress,
ethers.utils.parseEther("500")
);
Transaction Execution
// Execute custom transaction
const data = someContract.interface.encodeFunctionData(
"someFunction",
[param1, param2]
);
await distributor.execTransaction(
someContract.address,
0,
data
);
Security Operations
// Pause contract
await distributor.pause();
// Attempt operation (will fail)
await expect(
distributor.approveERC20(token, spender, amount)
).to.be.revertedWith("Pausable: paused");
// Unpause contract
await distributor.unpause();
Error Reference
Common Errors
| Error | Description | Solution |
|---|---|---|
Ownable: caller is not the owner | Unauthorized access attempt | Ensure operation is called by contract owner |
Pausable: paused | Operation attempted while paused | Wait for contract to be unpaused |
Tx failed | Transaction execution failed | Check target contract and parameters |
Error Handling
try {
await distributor.execTransaction(target, value, data);
} catch (error) {
if (error.message.includes("Pausable: paused")) {
// Handle paused state
} else if (error.message.includes("Ownable: caller is not the owner")) {
// Handle unauthorized access
} else {
// Handle other errors
}
}
Integration Guide
Contract Setup
// Deploy contract
const Distributor = await ethers.getContractFactory("RewardDistributor");
const distributor = await Distributor.deploy();
await distributor.deployed();
// Setup initial state
await distributor.approveERC20(token.address, spender.address, amount);
Security Best Practices
-
Access Control
- Always verify caller permissions
- Use multi-sig for critical operations
- Implement time-locks for sensitive changes
-
Token Safety
- Verify token contracts
- Use SafeERC20 for all operations
- Implement amount validation
-
Transaction Safety
- Validate target contracts
- Verify transaction data
- Implement value limits
Gas Optimization
Recommended Patterns
-
Batch Operations
// Instead of multiple single approvals
for (uint i = 0; i < tokens.length; i++) {
await distributor.approveERC20(tokens[i], spender, amounts[i]);
}
// Use batch execution
const data = encodeMultiApprove(tokens, spender, amounts);
await distributor.execTransaction(batchProcessor, 0, data); -
State Management
// Check state before operations
const paused = await distributor.paused();
if (!paused) {
// Execute operations
}
Event Monitoring
Event Filtering
// Listen for transactions
distributor.on("ExecTransaction", (from, to, value, data) => {
console.log(`Transaction executed by ${from} to ${to}`);
console.log(`Value: ${ethers.utils.formatEther(value)} ETH`);
});
// Filter specific events
const filter = distributor.filters.ExecTransaction(null, targetContract);
const events = await distributor.queryFilter(filter);
Testing Utilities
Test Helpers
// Gas estimation helper
async function estimateGas(
distributor: RewardDistributor,
token: string,
spender: string,
amount: BigNumber,
): Promise<BigNumber> {
return await distributor.estimateGas.approveERC20(token, spender, amount);
}
// Transaction simulation
async function simulateExecution(
distributor: RewardDistributor,
target: string,
data: string,
): Promise<void> {
await network.provider.send("evm_increaseTime", [3600]);
await distributor.execTransaction(target, 0, data);
}