Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion generator/features/assetListing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,13 @@ export const assetListing: FeatureModule<Listing[]> = {
assertGe(IERC20(aTokenAddress).balanceOf(address(${pool}.DUST_BIN)), 10 ** ${cfg.decimals});
}\n`;
if (isAddress(cfg.admin)) {
listingTest += `\nfunction test_${cfg.assetSymbol}Admin() public {
listingTest += `\nfunction test_${cfg.assetSymbol}LMAdmin() public {
${testExecuteProposal(pool)}
address a${cfg.assetSymbol} = ${pool}.POOL.getReserveAToken(proposal.${cfg.assetSymbol}());
address v${cfg.assetSymbol} = ${pool}.POOL.getReserveVariableDebtToken(proposal.${cfg.assetSymbol}());
assertEq(IEmissionManager(${pool}.EMISSION_MANAGER).getEmissionAdmin(proposal.${cfg.assetSymbol}()), proposal.${cfg.assetSymbol}_LM_ADMIN());
assertEq(IEmissionManager(${pool}.EMISSION_MANAGER).getEmissionAdmin(a${cfg.assetSymbol}), proposal.${cfg.assetSymbol}_LM_ADMIN());
assertEq(IEmissionManager(${pool}.EMISSION_MANAGER).getEmissionAdmin(v${cfg.assetSymbol}), proposal.${cfg.assetSymbol}_LM_ADMIN());
}\n`;
}
return listingTest;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {AaveV3Ethereum, AaveV3EthereumAssets} from 'aave-address-book/AaveV3Ethereum.sol';
import {AaveV3PayloadEthereum} from 'aave-helpers/src/v3-config-engine/AaveV3PayloadEthereum.sol';
import {EngineFlags} from 'aave-v3-origin/contracts/extensions/v3-config-engine/EngineFlags.sol';
import {IAaveV3ConfigEngine} from 'aave-v3-origin/contracts/extensions/v3-config-engine/IAaveV3ConfigEngine.sol';
import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import {SafeERC20} from 'openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol';
import {IEmissionManager} from 'aave-v3-origin/contracts/rewards/interfaces/IEmissionManager.sol';

/**
* @title Onboard syrupUSDC to Aave V3 Core Instance
* @author Aavechan Initiative @aci
* - Snapshot: https://snapshot.org/#/s:aavedao.eth/proposal/0xf5951af5d6d7d70be998a72c531708db3ff9c46b033e3e27bfd59fb87542d0ea
* - Discussion: https://governance.aave.com/t/arfc-onboard-syrupusdc-to-aave-v3-core-instance/22456
*/
contract AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421 is AaveV3PayloadEthereum {
using SafeERC20 for IERC20;

address public constant syrupUSDC = 0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b;
uint256 public constant syrupUSDC_SEED_AMOUNT = 100e6;
address public constant syrupUSDC_LM_ADMIN = 0xac140648435d03f784879cd789130F22Ef588Fcd;

function _postExecute() internal override {
_supplyAndConfigureLMAdmin(syrupUSDC, syrupUSDC_SEED_AMOUNT, syrupUSDC_LM_ADMIN);
}

function eModeCategoryCreations()
public
pure
override
returns (IAaveV3ConfigEngine.EModeCategoryCreation[] memory)
{
IAaveV3ConfigEngine.EModeCategoryCreation[]
memory eModeCreations = new IAaveV3ConfigEngine.EModeCategoryCreation[](1);

address[] memory collateralAssets_SyrupUSDC__USDC__USDT = new address[](1);
address[] memory borrowableAssets_SyrupUSDC__USDC__USDT = new address[](2);

collateralAssets_SyrupUSDC__USDC__USDT[0] = syrupUSDC;
borrowableAssets_SyrupUSDC__USDC__USDT[0] = AaveV3EthereumAssets.USDC_UNDERLYING;
borrowableAssets_SyrupUSDC__USDC__USDT[1] = AaveV3EthereumAssets.USDT_UNDERLYING;

eModeCreations[0] = IAaveV3ConfigEngine.EModeCategoryCreation({
ltv: 90_00,
liqThreshold: 92_00,
liqBonus: 4_00,
label: 'syrupUSDC__USDC__USDT',
collaterals: collateralAssets_SyrupUSDC__USDC__USDT,
borrowables: borrowableAssets_SyrupUSDC__USDC__USDT
});

return eModeCreations;
}
function newListings() public pure override returns (IAaveV3ConfigEngine.Listing[] memory) {
IAaveV3ConfigEngine.Listing[] memory listings = new IAaveV3ConfigEngine.Listing[](1);

listings[0] = IAaveV3ConfigEngine.Listing({
asset: syrupUSDC,
assetSymbol: 'syrupUSDC',
priceFeed: 0xE4E9d021D3A44E8bc9949690E298C6b41C6EF354,
enabledToBorrow: EngineFlags.DISABLED,
borrowableInIsolation: EngineFlags.DISABLED,
withSiloedBorrowing: EngineFlags.DISABLED,
flashloanable: EngineFlags.ENABLED,
ltv: 0,
liqThreshold: 0,
liqBonus: 0,
reserveFactor: 50_00,
supplyCap: 200_000_000,
borrowCap: 1,
debtCeiling: 0,
liqProtocolFee: 10_00,
rateStrategyParams: IAaveV3ConfigEngine.InterestRateInputData({
optimalUsageRatio: 45_00,
baseVariableBorrowRate: 0,
variableRateSlope1: 10_00,
variableRateSlope2: 300_00
})
});

return listings;
}
function _supplyAndConfigureLMAdmin(address asset, uint256 seedAmount, address lmAdmin) internal {
IERC20(asset).forceApprove(address(AaveV3Ethereum.POOL), seedAmount);
AaveV3Ethereum.POOL.supply(asset, seedAmount, address(AaveV3Ethereum.DUST_BIN), 0);

if (lmAdmin != address(0)) {
address aToken = AaveV3Ethereum.POOL.getReserveAToken(asset);
address vToken = AaveV3Ethereum.POOL.getReserveVariableDebtToken(asset);
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).setEmissionAdmin(asset, lmAdmin);
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).setEmissionAdmin(aToken, lmAdmin);
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).setEmissionAdmin(vToken, lmAdmin);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers} from 'aave-helpers/src/GovV3Helpers.sol';
import {AaveV3Ethereum} from 'aave-address-book/AaveV3Ethereum.sol';
import {IERC20} from 'openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import {IEmissionManager} from 'aave-v3-origin/contracts/rewards/interfaces/IEmissionManager.sol';

import 'forge-std/Test.sol';
import {ProtocolV3TestBase, ReserveConfig} from 'aave-helpers/src/ProtocolV3TestBase.sol';
import {AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421} from './AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421.sol';

/**
* @dev Test for AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421
* command: FOUNDRY_PROFILE=test forge test --match-path=src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421.t.sol -vv
*/
contract AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421_Test is ProtocolV3TestBase {
AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421 internal proposal;

function setUp() public {
vm.createSelectFork(vm.rpcUrl('mainnet'), 24927435);
proposal = new AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421();
}

/**
* @dev executes the generic test suite including e2e and config snapshots
*/
function test_defaultProposalExecution() public {
defaultTest(
'AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421',
AaveV3Ethereum.POOL,
address(proposal)
);
}

function test_dustBinHassyrupUSDCFunds() public {
GovV3Helpers.executePayload(vm, address(proposal));
address aTokenAddress = AaveV3Ethereum.POOL.getReserveAToken(proposal.syrupUSDC());
assertGe(IERC20(aTokenAddress).balanceOf(address(AaveV3Ethereum.DUST_BIN)), 100 * 10 ** 6);
}

function test_syrupUSDCLMAdmin() public {
GovV3Helpers.executePayload(vm, address(proposal));
address asyrupUSDC = AaveV3Ethereum.POOL.getReserveAToken(proposal.syrupUSDC());
address vsyrupUSDC = AaveV3Ethereum.POOL.getReserveVariableDebtToken(proposal.syrupUSDC());
assertEq(
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).getEmissionAdmin(proposal.syrupUSDC()),
proposal.syrupUSDC_LM_ADMIN()
);
assertEq(
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).getEmissionAdmin(asyrupUSDC),
proposal.syrupUSDC_LM_ADMIN()
);
Comment thread
Kogaroshi marked this conversation as resolved.
assertEq(
IEmissionManager(AaveV3Ethereum.EMISSION_MANAGER).getEmissionAdmin(vsyrupUSDC),
proposal.syrupUSDC_LM_ADMIN()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: "Onboard syrupUSDC to Aave V3 Core Instance"
author: "Aavechan Initiative @aci"
discussions: "https://governance.aave.com/t/arfc-onboard-syrupusdc-to-aave-v3-core-instance/22456"
snapshot: "https://snapshot.org/#/s:aavedao.eth/proposal/0xf5951af5d6d7d70be998a72c531708db3ff9c46b033e3e27bfd59fb87542d0ea"
---

## Simple Summary

This proposal seeks to onboard syrupUSDC — a USDC-based yield-bearing token issued by Maple Finance — as a collateral asset on Aave V3 Core Instance. syrupUSDC is built on top of Maple's infrastructure and offers access to overcollateralized, fixed-rate institutional loans, which provide high and consistent yields to DeFi users.

Maple, launched in 2021, is an on-chain asset manager whose team has decades of traditional finance and crypto experience. As of June 2025, Maple has $2.3b in AUM. Maple combines deep capital markets expertise with DeFi innovation to offer digital asset lending and yield products.

## Motivation

Onboarding syrupUSDC to Aave V3 Core Instance provides:

- New Token Type: A new collateral option backed by real yield from fixed-rate institutional lending strategies
- AAVE TVL: Maple has a large network of institutional capital allocators, ready to allocate $500M+ USDC/USDT into syrupUSDC if it is available on Aave as collateral to loop it and get to their hurdle rates.
- Higher Rates and Utilization: Increases USDC rates and utilization due to strong expected borrower demand.
- Growth Incentives: Maple has $250k of incentives available to bootstrap the growth for Aave users.

The Aave and Maple partnership will enable:

- New Yield Opportunities: Commercial alignment with Maple's large institutional network, unlocking additional yield generation opportunities for Aave.
- GHO Adoption: Maple can help with growing other strategic priorities for Aave, including GHO adoption. E.g., GHO lending to institutions.
- Future Collaboration: Future asset listings, including the Maple liquid yielding Bitcoin asset.

## Specification

It's a USDC-based, yield-bearing token whose principal and yield are backed by the secured lending strategy of Maple. (More details below).

Technical details: ERC-4626 token standard built on top of Maple's smart contracts.
High Yield. Maple has a track record of generating consistently high underlying yields of 7-15% net APY.

Loans are fully collateralized by digital assets ensuring lending positions are protected, even if borrowers default or asset prices fall. More on: https://app.maple.finance/earn.

The table below illustrates the configured risk parameters for **syrupUSDC**

| Parameter | Value |
| ------------------------- | -----------------------------------------: |
| Isolation Mode | false |
| Borrowable | DISABLED |
| Collateral Enabled | true |
| Supply Cap (syrupUSDC) | 200,000,000 |
| Borrow Cap (syrupUSDC) | 1 |
| Debt Ceiling | USD 0 |
| LTV | 0 % |
| LT | 0 % |
| Liquidation Bonus | 0 % |
| Liquidation Protocol Fee | 10 % |
| Reserve Factor | 50 % |
| Base Variable Borrow Rate | 0 % |
| Variable Slope 1 | 10 % |
| Variable Slope 2 | 300 % |
| Uoptimal | 45 % |
| Flashloanable | ENABLED |
| Siloed Borrowing | DISABLED |
| Borrowable in Isolation | DISABLED |
| Oracle | 0xe4e9d021d3a44e8bc9949690e298c6b41c6ef354 |

### E-Mode

| **Parameter** | **Value** | **Value** | **Value** |
| --------------------- | --------- | --------- | --------- |
| Asset | syrupUSDC | USDC | USDT |
| Collateral | Yes | No | No |
| Borrowable | No | Yes | Yes |
| Max LTV | 90.00% | - | - |
| Liquidation Threshold | 92.00% | - | - |
| Liquidation Bonus | 4.00% | - | - |

**CAPO**

| **maxYearlyRatioGrowthPercent** | **ratioReferenceTime** | **MINIMUM_SNAPSHOT_DELAY** |
| ------------------------------- | ---------------------- | -------------------------- |
| 19.94% | monthly | 7 |

### Oracle details

| **Parameter** | **Value** |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Oracle | [0xE4E9d021D3A44E8bc9949690E298C6b41C6EF354](https://etherscan.io/address/0xE4E9d021D3A44E8bc9949690E298C6b41C6EF354#readContract) |
| Ratio Provider | [syrupUSDC-USDC Exchange Rate](https://etherscan.io/address/0x80ac24aA929eaF5013f6436cdA2a7ba190f5Cc0b#readContract) |
| Underlying oracle | [USDC/USD](https://etherscan.io/address/0xB6557F02F0a5dA7b9D3C2d979cc19e00e756F6dA#readContract) |
| Minimum Snapshot delay | 7 days |
| Max yearly growth | 1994 (19.94%) |
| Last Answer | 116045418 ($1.16045418 on April 21st) |

Additionally [0xac140648435d03f784879cd789130F22Ef588Fcd](https://etherscan.io/address/0xac140648435d03f784879cd789130F22Ef588Fcd) has been set as the emission admin for syrupUSDC and the corresponding aToken, vToken and underlying token.

## Disclosure

ACI (Aave Chan Initiative) is not affiliated with Maple Finance and has not received compensation for creating this proposal.

### Useful links:

Website: https://maple.finance/
App: https://app.maple.finance/earn/details

## References

- Implementation: [AaveV3Ethereum](https://github.com/aave-dao/aave-proposals-v3/blob/main/src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421.sol)
- Tests: [AaveV3Ethereum](https://github.com/aave-dao/aave-proposals-v3/blob/main/src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421.t.sol)
- [Snapshot](https://snapshot.org/#/s:aavedao.eth/proposal/0xf5951af5d6d7d70be998a72c531708db3ff9c46b033e3e27bfd59fb87542d0ea)
- [Discussion](https://governance.aave.com/t/arfc-onboard-syrupusdc-to-aave-v3-core-instance/22456)

## Copyright

Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {GovV3Helpers, IPayloadsControllerCore, PayloadsControllerUtils} from 'aave-helpers/src/GovV3Helpers.sol';
import {GovernanceV3Ethereum} from 'aave-address-book/GovernanceV3Ethereum.sol';

import {EthereumScript} from 'solidity-utils/contracts/utils/ScriptUtils.sol';
import {AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421} from './AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421.sol';

/**
* @dev Deploy Ethereum
* deploy-command: make deploy-ledger contract=src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/OnboardSyrupUSDCToAaveV3CoreInstance_20260421.s.sol:DeployEthereum chain=mainnet
* verify-command: FOUNDRY_PROFILE=deploy npx catapulta-verify -b broadcast/OnboardSyrupUSDCToAaveV3CoreInstance_20260421.s.sol/1/run-latest.json
*/
contract DeployEthereum is EthereumScript {
function run() external broadcast {
// deploy payloads
address payload0 = GovV3Helpers.deployDeterministic(
type(AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421).creationCode
);

// compose action
IPayloadsControllerCore.ExecutionAction[]
memory actions = new IPayloadsControllerCore.ExecutionAction[](1);
actions[0] = GovV3Helpers.buildAction(payload0);

// register action at payloadsController
GovV3Helpers.createPayload(actions);
}
}

/**
* @dev Create Proposal
* command: make deploy-ledger contract=src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/OnboardSyrupUSDCToAaveV3CoreInstance_20260421.s.sol:CreateProposal chain=mainnet
*/
contract CreateProposal is EthereumScript {
function run() external {
// create payloads
PayloadsControllerUtils.Payload[] memory payloads = new PayloadsControllerUtils.Payload[](1);

// compose actions for validation
{
IPayloadsControllerCore.ExecutionAction[]
memory actionsEthereum = new IPayloadsControllerCore.ExecutionAction[](1);
actionsEthereum[0] = GovV3Helpers.buildAction(
type(AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance_20260421).creationCode
);
payloads[0] = GovV3Helpers.buildMainnetPayload(vm, actionsEthereum);
}

// create proposal
vm.startBroadcast();
GovV3Helpers.createProposal(
vm,
payloads,
GovernanceV3Ethereum.VOTING_PORTAL_ETH_AVAX,
GovV3Helpers.ipfsHashFile(
vm,
'src/20260421_AaveV3Ethereum_OnboardSyrupUSDCToAaveV3CoreInstance/OnboardSyrupUSDCToAaveV3CoreInstance.md'
)
);
}
}
Loading
Loading