Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature / Defi Positions #1062

Merged
merged 46 commits into from
Nov 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
bf6e290
defi positions init
stojnovsky Oct 22, 2024
c2715ad
fix conflicts
sonytooo Oct 31, 2024
c8cd6aa
added address for aave token in aave getter for defi positions
stojnovsky Oct 31, 2024
da3a73b
Merge branch 'feature/defi-positions' of github.com:AmbireTech/ambire…
stojnovsky Oct 31, 2024
30739f9
added: defi positions ctrl; libs result filtration fixes; types namin…
sonytooo Nov 1, 2024
051e231
add: required positionId + updatePositions in main
sonytooo Nov 1, 2024
d185a36
add: address to the assets
sonytooo Nov 4, 2024
adb5ce8
fixed aave position to return aave token address
stojnovsky Nov 4, 2024
cb6a426
Merge remote-tracking branch 'origin/v2' into feature/defi-positions
PetromirDev Nov 4, 2024
e62a757
fix: typo
sonytooo Nov 5, 2024
7830411
add: price to each asset
sonytooo Nov 5, 2024
fadb12d
update: defi positions use networkId, instead of network name
PetromirDev Nov 5, 2024
fa000db
netowrkId fixes in the ctrl
sonytooo Nov 5, 2024
13328d8
update: defi positions prices and decimals
PetromirDev Nov 5, 2024
f45e20e
merged with origin/feature/defi-positions
PetromirDev Nov 5, 2024
b7ae194
fix: aave no health factor (1.15)
PetromirDev Nov 5, 2024
8483906
get the aave asset price from the oracle instead of cena
sonytooo Nov 5, 2024
b10ab02
defi positions / added split returned assets by AAVE
stojnovsky Nov 5, 2024
bf89c9a
update(wip): defi positions structure
PetromirDev Nov 5, 2024
45653d6
Merge remote-tracking branch 'origin/feature/defi-positions' into fea…
PetromirDev Nov 5, 2024
43ac863
add: proper position value calculation
PetromirDev Nov 5, 2024
6743ab1
fix: aave decimals should be number
PetromirDev Nov 5, 2024
37e845e
fix: defi positions loading
PetromirDev Nov 5, 2024
9689818
refactor: defi positions provider location
PetromirDev Nov 6, 2024
10b0d41
add: defi positions error banners
PetromirDev Nov 6, 2024
755218a
delete: test error in uniV3
PetromirDev Nov 6, 2024
b934e7d
add: defi positions caching and improve error banner
PetromirDev Nov 6, 2024
44afd59
change: defipositions don't skip updates if there is a provider error
PetromirDev Nov 6, 2024
267de5b
update: defipositions include value in asset, sort assets, positions …
PetromirDev Nov 6, 2024
e5cf7e4
fixes
sonytooo Nov 6, 2024
5734b12
update defi on reloadSelectedAccount
sonytooo Nov 6, 2024
546eb81
fix: conflicts
sonytooo Nov 6, 2024
f946b19
Merge branch 'v2' into feature/defi-positions
sonytooo Nov 6, 2024
ea266de
Merge remote-tracking branch 'origin/v2' into feature/defi-positions
PetromirDev Nov 7, 2024
1e11763
change: reset provider errors before update (defi positions)
PetromirDev Nov 7, 2024
eb9ca4f
update: defi positions banners logic
PetromirDev Nov 7, 2024
2e29c2e
fix: defi positions unit tests
PetromirDev Nov 7, 2024
17cf09a
tests: update defi positions lib test
PetromirDev Nov 7, 2024
d7142a6
update: error handling and add controller test (defi positions)
PetromirDev Nov 7, 2024
a24a9fb
delete: math.random error
PetromirDev Nov 7, 2024
9694840
fix: defi position tests
PetromirDev Nov 7, 2024
563d8e8
change: don't update positions on controller init (defi positions)
PetromirDev Nov 7, 2024
9342c4f
delete: compile.test.js
PetromirDev Nov 7, 2024
171023a
change: defi positions don't console error if there is no selected ac…
PetromirDev Nov 7, 2024
5d59689
change: defi positions controller fetch
PetromirDev Nov 7, 2024
0b4c38b
Merge remote-tracking branch 'origin/v2' into feature/defi-positions
PetromirDev Nov 8, 2024
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
2 changes: 1 addition & 1 deletion contracts/compiled/AmbireAccount.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/compiled/AmbireFactory.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/compiled/AmbirePaymaster.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions contracts/compiled/DeFiAAVEPosition.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions contracts/compiled/DeFiUniswapV3Positions.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion contracts/compiled/DeployHelper.json

Large diffs are not rendered by default.

301 changes: 301 additions & 0 deletions contracts/deployless/DeFiAAVEPosition.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,301 @@
// SPDX-License-Identifier: agpl-3.0
pragma solidity 0.8.19;

struct OutcomeAddress {
address addr;
bool success;
bytes err;
}

struct OutcomeString {
string str;
bool success;
bytes err;
}

struct UserAccountData {
uint256 totalCollateralBase;
uint256 totalDebtBase;
uint256 availableBorrowsBase;
uint256 currentLiquidationThreshold;
uint256 ltv;
uint256 healthFactor;
}

struct AAVEInfo {
address poolAddr;
address underlyingAsset;
}

struct ReserveConfigurationMap {
//bit 0-15: LTV
//bit 16-31: Liq. threshold
//bit 32-47: Liq. bonus
//bit 48-55: Decimals
//bit 56: reserve is active
//bit 57: reserve is frozen
//bit 58: borrowing is enabled
//bit 59: stable rate borrowing enabled
//bit 60: asset is paused
//bit 61: borrowing in isolation mode is enabled
//bit 62: siloed borrowing enabled
//bit 63: flashloaning enabled
//bit 64-79: reserve factor
//bit 80-115 borrow cap in whole tokens, borrowCap == 0 => no cap
//bit 116-151 supply cap in whole tokens, supplyCap == 0 => no cap
//bit 152-167 liquidation protocol fee
//bit 168-175 eMode category
//bit 176-211 unbacked mint cap in whole tokens, unbackedMintCap == 0 => minting disabled
//bit 212-251 debt ceiling for isolation mode with (ReserveConfiguration::DEBT_CEILING_DECIMALS) decimals
//bit 252-255 unused

uint256 data;
}

struct ReserveData {
//stores the reserve configuration
ReserveConfigurationMap configuration;
//the liquidity index. Expressed in ray
uint128 liquidityIndex;
//the current supply rate. Expressed in ray
uint128 currentLiquidityRate;
//variable borrow index. Expressed in ray
uint128 variableBorrowIndex;
//the current variable borrow rate. Expressed in ray
uint128 currentVariableBorrowRate;
//the current stable borrow rate. Expressed in ray
uint128 currentStableBorrowRate;
//timestamp of last update
uint40 lastUpdateTimestamp;
//the id of the reserve. Represents the position in the list of the active reserves
uint16 id;
//aToken address
address aTokenAddress;
//stableDebtToken address
address stableDebtTokenAddress;
//variableDebtToken address
address variableDebtTokenAddress;
//address of the interest rate strategy
address interestRateStrategyAddress;
//the current treasury balance, scaled
uint128 accruedToTreasury;
//the outstanding unbacked aTokens minted through the bridging feature
uint128 unbacked;
//the outstanding debt borrowed against this asset in isolation mode
uint128 isolationModeTotalDebt;
}

struct ReserveDataIronclad {
ReserveConfigurationMap configuration;
uint128 liquidityIndex;
uint128 variableBorrowIndex;
uint128 currentLiquidityRate;
uint128 currentVariableBorrowRate;
uint128 currentStableBorrowRate;
uint40 lastUpdateTimestamp;
address aTokenAddress;
address stableDebtTokenAddress;
address variableDebtTokenAddress;
address interestRateStrategyAddress;
uint8 id;
}

struct TokenFromBalance {
address addr;
string symbol;
uint256 balance;
uint8 decimals;
uint256 price;
uint256 borrowAssetBalance;
uint256 stableBorrowAssetBalance;
uint128 currentLiquidityRate;
uint128 currentVariableBorrowRate;
uint128 currentStableBorrowRate;
}

struct AAVEUserBalance {
TokenFromBalance[] userBalance;
UserAccountData accountData;
bytes userBalanceErr;
bytes accountDataErr;

}

interface IPoolAddressesProvider {
function getPriceOracle() external view returns (address);
}

interface IAaveOracle {
function getAssetPrice(address asset) external view returns (uint256);
}

interface IATOKEN {
function balanceOf(address) external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function POOL() external view returns (address);
function scaledBalanceOf(address) external view returns (uint256);
function scaledTotalSupply() external view returns (uint256);
function nonces(address) external view returns (uint256);
function UNDERLYING_ASSET_ADDRESS() external view returns (address);
}

interface IPOOL {
// optimism (0x794a61358D6845594F94dc1DB02A252b5b4814aD)
// mainnet (0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2)
function ADDRESSES_PROVIDER() external view returns (address);
function getAddressesProvider() external view returns (address);
function getBorrowLogic() external view returns (address);
function getPoolLogic() external view returns (address);
function getReservesList() external view returns (address[] memory);
function getReserveData(address reserveAddr) external view returns (ReserveData memory);
function getUserAccountData(address userAddress) external view returns (UserAccountData memory);
}

interface IPOOLIronclad {
// optimism (0x794a61358D6845594F94dc1DB02A252b5b4814aD)
// mainnet (0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2)
function ADDRESSES_PROVIDER() external view returns (address);
function getAddressesProvider() external view returns (address);
function getBorrowLogic() external view returns (address);
function getPoolLogic() external view returns (address);
function getReservesList() external view returns (address[] memory);
function getReserveData(address reserveAddr) external view returns (ReserveDataIronclad memory);
function getUserAccountData(address userAddress) external view returns (UserAccountData memory);
}


contract CALLS {
function ADDRESSES_PROVIDER(address poolAddress) external view returns (address) {
return IPOOL(poolAddress).ADDRESSES_PROVIDER();
}

function getAddressesProvider(address poolAddress) external view returns (address) {
return IPOOL(poolAddress).getAddressesProvider();
}

function getTokenSymbol(address tokenAddr) external view returns (string memory) {
return IATOKEN(tokenAddr).symbol();
}
}


contract AAVEPosition {
CALLS calls = new CALLS();
function ADDRESSES_PROVIDER(address poolAddress) internal view returns (OutcomeAddress memory outcome) {
try calls.ADDRESSES_PROVIDER(poolAddress) returns (address result) {
outcome.addr = result;
outcome.success = true;
} catch (bytes memory err) {
outcome.err = err;
outcome.success = false;
}
}

function getAddressesProvider(address poolAddress) internal view returns (OutcomeAddress memory outcome) {
try calls.getAddressesProvider(poolAddress) returns (address result) {
outcome.addr = result;
outcome.success = true;
} catch (bytes memory err) {
outcome.err = err;
outcome.success = false;
}
}

function getTokenSymbolTry(address tokenAddr) internal view returns (OutcomeString memory outcome) {
try calls.getTokenSymbol(tokenAddr) returns (string memory result) {
outcome.str = result;
outcome.success = true;
} catch (bytes memory err) {
outcome.err = err;
outcome.success = false;
}
}

function getTokenSymbol(address baseAddr) internal view returns (string memory outcome) {
OutcomeString memory result = getTokenSymbolTry(baseAddr);
if (result.success) {
outcome = result.str;
} else {
outcome = 'error';
}
}

function getTokenBalancesFromPool(address userAddr, address poolAddress) external view returns (TokenFromBalance[] memory, bytes memory err) {
bool standartAAVE = true;
bool isError = false;
address[] memory reserves = IPOOL(poolAddress).getReservesList();

address provider;
OutcomeAddress memory providerOutcome = ADDRESSES_PROVIDER(poolAddress);
if (providerOutcome.success == false) {
providerOutcome = getAddressesProvider(poolAddress);
if (providerOutcome.success) {
provider = providerOutcome.addr;
} else {
err = providerOutcome.err;
isError = true;
}
standartAAVE = false;
} else {
provider = providerOutcome.addr;
}

uint reservesLen = reserves.length;
TokenFromBalance[] memory userBalance = new TokenFromBalance[](reservesLen);

if (isError) {
return (userBalance, err);
}

address priceOralceAddr = IPoolAddressesProvider(provider).getPriceOracle();
for (uint256 i = 0; i < reservesLen; i++) {
if (standartAAVE) {
ReserveData memory reserveData = IPOOL(poolAddress).getReserveData(reserves[i]);
uint256 price = IAaveOracle(priceOralceAddr).getAssetPrice(reserves[i]);
TokenFromBalance memory aToken;
aToken.addr = reserveData.aTokenAddress;
aToken.balance = IATOKEN(reserveData.aTokenAddress).balanceOf(userAddr);
aToken.symbol = getTokenSymbol(reserves[i]);
aToken.decimals = IATOKEN(reserveData.aTokenAddress).decimals();
aToken.price = price;
aToken.borrowAssetBalance = IATOKEN(reserveData.variableDebtTokenAddress).balanceOf(userAddr);
aToken.stableBorrowAssetBalance = IATOKEN(reserveData.stableDebtTokenAddress).balanceOf(userAddr);
aToken.currentLiquidityRate = reserveData.currentLiquidityRate;
aToken.currentVariableBorrowRate = reserveData.currentVariableBorrowRate;
aToken.currentStableBorrowRate = reserveData.currentStableBorrowRate;
userBalance[i] = aToken;
} else {
ReserveDataIronclad memory reserveData = IPOOLIronclad(poolAddress).getReserveData(reserves[i]);
uint256 price = IAaveOracle(priceOralceAddr).getAssetPrice(reserves[i]);
TokenFromBalance memory aToken;
aToken.addr = reserveData.aTokenAddress;
aToken.balance = IATOKEN(reserveData.aTokenAddress).balanceOf(userAddr);
aToken.symbol = getTokenSymbol(reserves[i]);
aToken.decimals = IATOKEN(reserveData.aTokenAddress).decimals();
aToken.price = price;
aToken.borrowAssetBalance = IATOKEN(reserveData.variableDebtTokenAddress).balanceOf(userAddr);
aToken.stableBorrowAssetBalance = IATOKEN(reserveData.stableDebtTokenAddress).balanceOf(userAddr);
aToken.currentLiquidityRate = reserveData.currentLiquidityRate;
aToken.currentVariableBorrowRate = reserveData.currentVariableBorrowRate;
aToken.currentStableBorrowRate = reserveData.currentStableBorrowRate;
userBalance[i] = aToken;
}
}
return (userBalance, err);
}

function getUserAccountData(address userAddr, address poolAddress) external view returns (UserAccountData memory result, bytes memory err) {
return (IPOOL(poolAddress).getUserAccountData((userAddr)), err);
}
}


contract DeFiAAVEPosition {
AAVEPosition positions = new AAVEPosition();
function getAAVEPosition(address userAddr, address poolAddr) external view returns (AAVEUserBalance memory result) {
(result.userBalance, result.accountDataErr) = positions.getTokenBalancesFromPool(userAddr, poolAddr);
(result.accountData, result.accountDataErr) = positions.getUserAccountData(userAddr, poolAddr);
return result;
}
}
Loading
Loading