πAaveImpact
The AaveImpact contract manages deposits and withdrawal functionalities for Non-Governmental Organizations (NGOs). It enables users to deposit various ERC20 tokens such as USDT, USDC and DAI supported by the Aave protocol, allocating a portion to NGO operations while earning yields. The contract interacts with the Aave lending pool for supplying assets and withdrawing them. It incorporates percentage-based sharing mechanisms, reward distributions from yields, and comprehensive security controls. It includes various functions and modifiers to manage NGO operations, such as updating NGO details, handling donations, and ensuring compliance with specific rules. The notBanned modifier is used to restrict access to deposits, ensuring that only non-banned entities can deposit while everyone can withdraw their deposited funds. Supports deposits and withdrawals for tokens validated by the factory contract.
Contract Architecture
Upgrade Mechanism
The contract implements the UUPS (Universal Upgradeable Proxy Standard) pattern:
Uses OpenZeppelin's
UUPSUpgradeableframeworkUpgrades are controlled through the
_authorizeUpgradefunctionOnly the contract owner can initiate upgrades
State variables are preserved during upgrades through proxy delegation
Upgrade Control
The upgrade process is controlled through two main components:
Authorization Function
function _authorizeUpgrade(address newImplementation) internal override onlyOwnerAuthorizes contract upgrades in the UUPS pattern.
Access Control:
Restricted to contract owner
Parameters:
newImplementation: Address of new implementation contract
Security Considerations:
Critical function for contract upgradeability
Must be called through proxy
Requires careful implementation validation
Should maintain contract invariants
Usage:
Part of upgrade process
Called automatically by upgrade mechanism
Validates upgrade permissions
Proxy Pattern
Uses ERC1967 proxy standard
Maintains separation of concerns
Preserves contract state
Upgrade Process
Owner initiates upgrade with new implementation
_authorizeUpgradevalidates permissionProxy updates implementation pointer
State remains intact in proxy storage
Core Logic and Operations
Supply Mechanism
Percentage Calculation
NGO share percentage uses a base of 10000 for precise calculations
100% = 10000 and 1% = 100
Valid range: MIN_SHARE_PERCENT (100 = 1%) to MAX_SHARE_PERCENT (10000 = 100%)
Example: 5000 represents 50% share to NGO
Minimum Deposit Requirements
Minimum supply amount: 1000 wei (defined by MIN_AMOUNT constant)
All supply operations require user not to be banned
Deposits cannot be made after NGO is marked as finished
Asset Distribution
User portion: (100% - NGO percentage) of deposited amount
NGO portion: NGO percentage of depsited amount
Rewards (yields) are calculated based on total shares, with NGO receiving proportional rewards
Token Support
USDT
USDC
DAI
Reward Management
Reward Calculation
Rewards tracked through _lastNGOBalance per token
pendingRewardsCalculation() updates pending rewards by:
Comparing current balance with last recorded NGO balance plus pending rewards
Adding proportional rewards to pendingNGORewards based on NGO shares ratio
Reward Distribution
Handled by oracle through handleNGOShareDistribution
Calculate pending rewards for specific token
Take platform fee (5% - SFI_FEE)
Transfer fee to platform address
Transfer remaining rewards to rewardsOwner
Update lastNGOBalance and reset pending rewards
Withdrawal System
Request Process
Users initiate withdrawals through
withdrawAmount constraints:
Minimum: 100 wei (MIN_WITHDRAWAL_AMOUNT)
Maximum: User's total balance (user shares + NGO shares)
If remaining balance < WITHDRAW_GAP (100 wei), withdraw full amount
Withdrawal Methods
Direct token withdrawal from Aave pool
Withdraw in original token
No queue or waiting period
Minimum withdrawal: 100 wei
Asset Recalculation
Withdrawals trigger proportional reduction of:
User's shares
NGO shares
Total shares and NGO shares
Last NGO balance
Inheritance Structure
Contract Storage Structure
State Variables
Key Storage Mappings
Important Constants
Data Structures
Structs
Struct representing initial deposit information for a user.
Function Documentation
constructor
constructorDisables initializers at deployment.
initialize
initializeInitializes the NGO contract.
Parameters
_aavePoolAddress: Aave pool contract_rewardOwnerAddress: Rewards recipientowner: NGO owner addressoracle: Oracle address_factoryAddress: Factory contract address
Validation
No zero addresses allowed
Effects
Initializes base contracts
Sets up initial configuration
Sets deposit ID to 1
deposit
depositDeposits ERC20 tokens to the NGO contract via Aave.
Parameters
_tokenAddress: Token to deposit_tokenAmount: Amount to deposit (in wei)_ngoPercent: NGO share percentage (100 = 1%, 10000 = 100%)
Constraints
Must not be banned
NGO must not be finished
Token must be valid via factory
Percentage must be between MIN_SHARE_PERCENT and MAX_SHARE_PERCENT
withdraw
withdrawWithdraws tokens from the NGO contract via Aave.
Parameters
amount: Amount to withdraw (in wei)_id: Deposit identifier_tokenAddress: Token to withdraw
Constraints
Amount >= MIN_WITHDRAWAL_AMOUNT
Amount <= user balance
Token must be valid via factory
withdrawCalculation
withdrawCalculationInternal function for processing withdrawal mathematics.
Parameters
_amount: Amount to withdraw in wei_id: Deposit identifier_userBalance: User's current balance_tokenAddress: Token address
Calculation Steps With Explanation
Calculate Ratio
Determines what fraction of user's total balance is being withdrawn
DIVIDER used for precision
Calculate Shares to Withdraw
Compute user shares and NGO shares to withdraw based on ratio
Formula:
user_ngo_share * total_ngo_assets / total_ngo_shares
State Updates
Reduce user's user shares and NGO shares
Reduce total shares and total NGO shares
Update last NGO balance
Example Calculation Let's say:
User balance: 150 tokens
User wants to withdraw 30 tokens
Calculate ratio: 30 * DIVIDER / 150 = 0.2 * DIVIDER
Reduce shares and userAssets proportionally
Final balance reduced by 20%
Important Considerations
All calculations maintain proportional relationships
Precision is maintained using DIVIDER
Both user assets and NGO shares are reduced proportionally
This function is critical for maintaining correct balances and proportions during withdrawals while ensuring both user assets and NGO shares are properly accounted for.
Internal Calculation Functions
pendingRewardsCalculation
Calculates and updates pending rewards for the NGO based on balance changes for a token.
Process
Compares current balance with last NGO balance plus pending rewards
If current balance is higher:
Calculates reward difference
Adds proportional amount (based on NGO shares ratio) to pending NGO rewards
Updates last NGO balance
State Changes
Updates _pendingNGORewards
Modifies _totalNGOAssets
Usage
Called before deposit asset calculations
Called during withdrawal processing
Called during reward distribution
Dependencies:
Relies on _balanceBeforeDeposit for current balance snapshot
assetsCalculation
Calculates and distributes deposited assets between user and NGO portions.
Parameters:
_amount: Amount deposited in tokens
_percent: NGO share percentage (100-10000)
_tokenAddress: Token address
Process:
NGO Asset Calculation
Calculates NGO portion using percentage
Assigns remaining amount to user's direct assets
Share Distribution
Creates deposit information record
Calculates NGO and user shares based on total shares and last NGO balance
State Updates
Updates user's asset and share records
Increments total shares and NGO assets
Updates lastNGOBalance
State Changes:
Updates _assets, _userShares, _ngoShares
Modifies _totalShares, _totalNGOShares
Updates _lastNGOBalance
Usage:
Called by deposit()
Administrative Functions
handleNGOShareDistribution
handleNGOShareDistributionManages the distribution of NGO rewards for a specific token
Access Control
Only callable by oracle
Calculations
Calculates pending rewards
Takes SFI platform fee (5%)
Effects
Updates NGO asset totals
Transfers fees to platform
Transfers remaining rewards to NGO
Updates last balance tracking
setOracle
setOracleManages oracle permissions.
Parameters
_newOracle: Address to modify oracle status_state: True to grant oracle role, false to revoke
setRewardsOwner
setRewardsOwnerUpdates rewards recipient.
Parameters
_newRewOwner: New recipient address
endNGO
endNGOTerminates the NGO contract.
Effects
Sets
isFinishto truePrevents new deposits
Allows existing withdrawals
setUserBan
setUserBanControls user access to supply functionality.
Parameters
userAddress: Address to ban/unbanisBan: True to ban, false to unban
Access Control
Only callable by owner
Effects
Updates user's ban status
Banned users can withdraw but cannot deposit
emitEvent
emitEventEmits NGO metadata for indexing.
Parameters
_name: NGO name_imageLink: NGO image URL_description: NGO description_link: NGO website/resource link_location: NGO location
Access Control
Only callable by owner
Usage
Used for updating NGO information in external systems
Enables graph indexing of NGO details
View Functions
getUserBalance
getUserBalanceReturns user's total balance for a specific token and deposit ID.
Parameters
_user: User address_id: Deposit identifier_tokenAddress: Token address
Returns
Total balance in ERC 20 Token [USDT/USDT/DAI]
getUserDepositInfo
getUserDepositInfoReturns deposit details for given user and ID.
Parameters
_id: Deposit identifier
Returns
Struct containing:
tokenAddress: Token addresspercent: NGO share percentageamount: Original deposit amountstartDate: Deposit timestamp
Modifiers
onlyOracle
Modifier to restrict access to only oracle.
notFinished
Modifier to restrict access to only oracle.
validDeposit
Modifier to check valid deposit info.
notBanned
Modifier to check is user is banned.
validAmount
Modifier to check valid minimum amount.
validWithdrawalAmount
Modifier to check valid minimum amount.
Events
Supply Events
Deposit
Emitted when a user deposits funds in the NGO.
Parameters
_depositId: Unique identifier for the deposit_depositor: Address of the depositing user_amounDeposited: Amount of tokens deposited_percentShare: Percentage shared with NGO (100-10000)_ngo: Address of the NGO contract_timestamp: Block timestamp of deposit_blockNumber: Block number of deposit_tokenAddress: Token address
Tracks : deposit ID, depositor address, amount, NGO share percentage, timestamp
Usage : Track new deposits and token used
Reward Events
RewardsUpdated
Emitted when NGO rewards are distributed.
Parameters
totalNGOAssets: Amount of tokens in the NGO pool._timestamp: Block timestamp of distribution_blockNumber: Block number of distribution
Tracks: total tokens in NGO pool, share distribution timestamp and block number.
Usage: Monitor reward distributions and track NGO earnings
Withdrawal Events
Withdraw
Emitted when a user withdraws funds.
Parameters
_claimer: The address of the user claiming withdrawal_ngo: The address of the NGO contract_amount: The amount withdrawn_timestamp: The block timestamp when withdraw was claimed_blockNumber: The block number when withdraw was claimed_depositId: The id of the deposit_tokenAddress: The address of the token being withdrawn
Tracks: claimer, amount, deposit ID, token
Usage: Track completed withdrawals
Administrative Events
GraphEvent
Emitted when NGO metadata is updated.
Parameters
_name: The name of the NGO_imageLink: The link to the image associated with the NGO_description: A description of the NGO_link: A link associated with the NGO_location: Physical location of NGO_ngo: The address of the NGO contract_timestamp: The block timestamp when withdraw was claimed
Tracks: NGO details and location
Usage: Track NGO metadata updates for indexing
NGOFinished
Emitted when NGO operations are terminated.
Parameters
_ngo: The address of the NGO contract_timestamp: The timestamp when the NGO was finished_blockNumber: The block number when the NGO was finished
Tracks: termination timestamp and block number and address of NGO Contract.
Usage: Signal end of NGO contract.
OracleChanged
Emitted when the oracle was added or status was changed.
Parameters
_newOracle: New oracle address_state:Current oracle state
Note: If state = true - current address active. If state = false - current address inactive.
Tracks: New oracle address and current oracle state.
Usage: Signals change of an Oracle.
RewardsOwnerChanged
Emitted when the rewards owner was changed.
Parameters
_newRewOwner: New reward owner address
Tracks: New Reward Owner address.
Usage: Signals change of Reward Owner.
BannedUser
Emitted when the state of user access is changed.
Parameters
_userAddress: User address_isBan: Current user state
Tracks: User address and access state of user.
Usage: Signals change of User access status.
Error Conditions
Validation Errors
InvalidPercent
Trigger: Share percentage outside valid range (100-10000)
Prevention: Validate percentage before depositing
Impact: Prevents invalid share calculations
InvalidDepositAmount
Trigger: Invalid deposit amount
Prevention: Ensure deposit amount is valid
Impact: Ensures economic viability of deposits
InvalidWithdrawalAmount
Trigger: Withdrawal request below minimum limit 100 wei
Prevention: Make sure the withdrawal amount >= 100 wei
Impact: Ensures economic viability of withdrawals
InvalidWithdrawAmount
Trigger: Withdrawal ratio calculates to zero (very small relative to balance)
Prevention: Withdraw larger amounts
Impact: Prevents micro-withdrawals
RequestAmountTooSmall
Trigger: Withdrawal request below minimum limit
Parameter:
_amount- Requested amountPrevention: Check minimum withdrawal amount
Impact: Ensures economic viability of withdrawals
RequestAmountTooLarge
Trigger: Withdrawal request above user balance
Parameter:
_amount- Requested amountPrevention: Check user balance
Impact: Prevents overdraw attempts
TokenNotAllowed
Trigger : Token address not allowed for deposit (though not used; see NotExist)
Prevention: Use valid tokens from factory
Impact: Ensures only supported tokens
NotExist
Trigger: Token does not exist in factory's validDepositTokenAddresses
Prevention: Check factory for valid tokens
Impact: Prevents invalid token operations
AaveWithdrawnAmountMismatch
Trigger: Aave withdraw returns different amount than requested
Parameters : expected, actual amounts
Prevention: Ensure Aave pool consistency
Impact: Protects against protocol mismatches
Access Control Errors
OnlyOracle
Trigger: Non-oracle address calling oracle-restricted function
Parameter:
_sender- Unauthorized caller addressPrevention: Use correct oracle address
Impact: Protects reward distribution mechanism
UserBanned
Trigger: Banned user attempting to supply
Prevention: Check ban status before supply
Impact: Enforces user restrictions
State Errors
NgoFinished
Trigger: Attempting operations after NGO termination
Prevention: Check NGO status before operations
Impact: Prevents post-termination activities
NotFinalizedStatus
Trigger: Claiming withdrawal before finalization
Prevention: Wait for withdrawal finalization
Impact: Ensures proper withdrawal sequence
RewardError
Trigger: Attempting reward distribution with no rewards
Prevention: Check reward balance before distribution
Impact: Prevents empty reward distributions
Technical Errors
NullAddress
Trigger: Providing zero address for critical parameters
Prevention: Validate addresses before use
Impact: Prevents contract initialization with invalid addresses
InvalidRequestIdForUser
Trigger: Claiming withdrawal for wrong request ID
Parameters:
_claimer: Address attempting claim_requestId: Invalid request ID
Prevention: Verify request ownership
Impact: Protects withdrawal ownership
ZeroAmount
Trigger: Attempting operation with zero amount
Prevention: Validate amount before operation
Impact: Prevents meaningless transactions
FeeError
Trigger: Attempting to transfer zero fee
Prevention: Ensure fee is not zero
Impact: Handles failed fee transfers
Security Features
Administrative Controls
Owner-only administrative functions
Contract upgrades (_authorizeUpgrade)
Oracle management (setOracle)
Rewards owner management (setRewardsOwner)
User banning (setUserBan)
NGO termination (endNGO)
Oracle-only functions
Reward distribution (handleNGOShareDistribution)
User Restrictions
Ban system for malicious users
Banned users can withdraw but cannot deposit
Safety Checks
Reentrancy protection on withdrawals
Amount validation
Balance verification
Null address checks
Upgradability
UUPS proxy pattern
Owner-controlled upgrades
State preservation during upgrades
Last updated
