Skip to content

Commit

Permalink
refactor data structures
Browse files Browse the repository at this point in the history
  • Loading branch information
daopunk committed Jul 14, 2024
1 parent f2cf1d9 commit 6134c56
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 63 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"test:coverage": "forge coverage --report lcov && lcov --ignore-errors unused --remove lcov.info 'node_modules/*' 'script/*' 'test/*' 'src/contracts/for-test/*' 'src/libraries/*' -o lcov.info.pruned && mv lcov.info.pruned lcov.info && genhtml -o coverage-report lcov.info"
},
"dependencies": {
"@opendollar/contracts": "0.0.0-984c17c2",
"@opendollar/contracts": "0.0.0-161d9907",
"@openzeppelin-contracts-3.4.2-solc-0.7": "yarn:@openzeppelin/contracts@^3.4.2",
"@openzeppelin/contracts": "4.9.6",
"@paraswap/sdk": "^6.7.0",
Expand Down
49 changes: 39 additions & 10 deletions script/getSwapRoute.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,33 @@ const paraSwapMin = constructSimpleSDK({chainId: 42161, axios});

const args = process.argv.slice(2);

const FROM_TOKEN = args[0];
const FROM_DECIMALS = args[1];
const TO_TOKEN = args[2];
const TO_DECIMALS = args[3];
const SELL_AMOUNT = args[4];
const CALLER = args[5];

async function getSwapRoute(_fromToken, _fromDecimals, _toToken, _toDecimals, _sellAmount, _caller) {
let FROM_TOKEN;
let FROM_DECIMALS;
let TO_TOKEN;
let TO_DECIMALS;
let SELL_AMOUNT;
let CALLER;

if (args.length) {
FROM_TOKEN = args[0];
FROM_DECIMALS = args[1];
TO_TOKEN = args[2];
TO_DECIMALS = args[3];
SELL_AMOUNT = args[4];
CALLER = args[5];
} else {
FROM_TOKEN = "0x221A0f68770658C15B525d0F89F5da2baAB5f321";
FROM_DECIMALS = "18";
TO_TOKEN = "0xEC70Dcb4A1EFa46b8F2D97C310C9c4790ba5ffA8";
TO_DECIMALS = "18";
SELL_AMOUNT = "995173078713564046713";
CALLER = "0x37c5B029f9c3691B3d47cb024f84E5E257aEb0BB";
}


async function getSwapRoute(_fromToken, _fromDecimals, _toToken, _toDecimals, _sellAmount, _caller, _num) {
// console.log(`\n ROUTE \n`);

const priceRoute = await paraSwapMin.swap.getRate({
srcToken: _fromToken,
srcDecimals: _fromDecimals,
Expand All @@ -23,6 +42,10 @@ async function getSwapRoute(_fromToken, _fromDecimals, _toToken, _toDecimals, _s
side: SwapSide.SELL,
});

console.log(`\n${_num}\nSRC: ${priceRoute.srcUSD}\nDST: ${priceRoute.destUSD}\nDIF: ${priceRoute.srcUSD - priceRoute.destUSD}\n\n`);
// console.log(JSON.stringify(priceRoute, null, 3));
// console.log(`\n TRANSACTION \n`);

const txParams = await paraSwapMin.swap.buildTx(
{
srcToken: priceRoute.srcToken,
Expand All @@ -35,7 +58,13 @@ async function getSwapRoute(_fromToken, _fromDecimals, _toToken, _toDecimals, _s
}
);

process.stdout.write(txParams.data);
// console.log(JSON.stringify(txParams, null, 3));

// process.stdout.write(txParams.data);
}

getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, SELL_AMOUNT, CALLER);
getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, "995173078713564046713", CALLER, "1");
getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, "4975865393567820237063", CALLER, "2");
getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, "9951730787135640477624", CALLER, "3");
getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, "49758653935678202402106", CALLER, "4");
getSwapRoute(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, "99517307871356404804213", CALLER, "5");
41 changes: 41 additions & 0 deletions script/getSwapTransaction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const {constructSimpleSDK, SwapSide} = require('@paraswap/sdk');
const axios = require('axios');

const paraSwapMin = constructSimpleSDK({chainId: 42161, axios});

const args = process.argv.slice(2);

const FROM_TOKEN = args[0];
const FROM_DECIMALS = args[1];
const TO_TOKEN = args[2];
const TO_DECIMALS = args[3];
const SELL_AMOUNT = args[4];
const CALLER = args[5];

async function getSwapTransaction(_fromToken, _fromDecimals, _toToken, _toDecimals, _sellAmount, _caller) {
const priceRoute = await paraSwapMin.swap.getRate({
srcToken: _fromToken,
srcDecimals: _fromDecimals,
destToken: _toToken,
destDecimals: _toDecimals,
amount: _sellAmount,
userAddress: _caller,
side: SwapSide.SELL,
});

const txParams = await paraSwapMin.swap.buildTx(
{
srcToken: priceRoute.srcToken,
destToken: priceRoute.destToken,
srcAmount: priceRoute.srcAmount,
destAmount: priceRoute.destAmount,
priceRoute,
userAddress: _caller,
ignoreChecks: true
}
);

process.stdout.write(txParams.data);
}

getSwapTransaction(FROM_TOKEN, FROM_DECIMALS, TO_TOKEN, TO_DECIMALS, SELL_AMOUNT, CALLER);
59 changes: 25 additions & 34 deletions src/leverage/ParaswapSellAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import {IPoolAddressesProvider} from '@aave-core-v3/contracts/interfaces/IPoolAd
// import {PercentageMath} from '@aave-core-v3/contracts/protocol/libraries/math/PercentageMath.sol';
import {IParaSwapAugustusRegistry} from '@aave-debt-swap/dependencies/paraswap/IParaSwapAugustusRegistry.sol';
import {ODProxy} from '@opendollar/contracts/proxies/ODProxy.sol';
import {IODSafeManager} from '@opendollar/interfaces/proxies/IODSafeManager.sol';
import {ICollateralJoinFactory} from '@opendollar/interfaces/factories/ICollateralJoinFactory.sol';
import {IVault721} from '@opendollar/interfaces/proxies/IVault721.sol';
import {ISAFEEngine} from '@opendollar/interfaces/ISAFEEngine.sol';
import {IParaswapSellAdapter} from 'src/leverage/interfaces/IParaswapSellAdapter.sol';
import {
ISystemCoin,

Check warning on line 12 in src/leverage/ParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

imported name ISystemCoin is not used
IODSafeManager,
ICollateralJoinFactory,
IVault721
} from '@opendollar/libraries/OpenDollarV1Arbitrum.sol';
import {IParaswapSellAdapter, InitSellAdapter} from 'src/leverage/interfaces/IParaswapSellAdapter.sol';
import {IParaswapAugustus} from 'src/leverage/interfaces/IParaswapAugustus.sol';
import {ExitActions} from 'src/leverage/ExitActions.sol';

Expand All @@ -22,7 +24,6 @@ import {ExitActions} from 'src/leverage/ExitActions.sol';
* - add modifiable contract for var updates
* - add withdraw function
* - enforce max slippage rate
* - simplify the constructor with a struct
* - remove Test inheritance
*/
contract ParaswapSellAdapter is FlashLoanSimpleReceiverBase, IParaswapSellAdapter, Test {
Expand All @@ -32,7 +33,6 @@ contract ParaswapSellAdapter is FlashLoanSimpleReceiverBase, IParaswapSellAdapte

IParaSwapAugustusRegistry public immutable AUGUSTUS_REGISTRY;
ODProxy public immutable PS_ADAPTER_ODPROXY;
IERC20Metadata public immutable OPEN_DOLLAR;

IParaswapAugustus public augustus;

Expand All @@ -44,33 +44,16 @@ contract ParaswapSellAdapter is FlashLoanSimpleReceiverBase, IParaswapSellAdapte

mapping(address => mapping(address => uint256)) internal _deposits;

/**
* @param _augustusRegistry address of Paraswap AugustusRegistry
* @param _augustusSwapper address of Paraswap AugustusSwapper
* @param _poolProvider address of Aave PoolAddressProvider
* @param _vault721 address of OpenDollar Vault721
* @param _exitActions address of OpenDollar ExitActions
* @param _collateralJoinFactory address of OpenDollar CollateralJoinFactory
* @param _coinJoin address of OpenDollar CoinJoin
*/
constructor(
address _systemCoin,
address _augustusRegistry,
address _augustusSwapper,
address _poolProvider,
address _vault721,
address _exitActions,
address _collateralJoinFactory,
address _coinJoin
) FlashLoanSimpleReceiverBase(IPoolAddressesProvider(_poolProvider)) {
OPEN_DOLLAR = IERC20Metadata(_systemCoin);
AUGUSTUS_REGISTRY = IParaSwapAugustusRegistry(_augustusRegistry);
augustus = IParaswapAugustus(_augustusSwapper);
IVault721 _v721 = IVault721(_vault721);
constructor(InitSellAdapter memory _initSellAdapter)
FlashLoanSimpleReceiverBase(IPoolAddressesProvider(_initSellAdapter.poolProvider))
{
AUGUSTUS_REGISTRY = IParaSwapAugustusRegistry(_initSellAdapter.augustusRegistry);
augustus = IParaswapAugustus(_initSellAdapter.augustusSwapper);
IVault721 _v721 = IVault721(_initSellAdapter.vault721);
safeManager = IODSafeManager(_v721.safeManager());
exitActions = ExitActions(_exitActions);
collateralJoinFactory = ICollateralJoinFactory(_collateralJoinFactory);
coinJoin = _coinJoin;
exitActions = ExitActions(_initSellAdapter.exitActions);
collateralJoinFactory = ICollateralJoinFactory(_initSellAdapter.collateralJoinFactory);
coinJoin = _initSellAdapter.coinJoin;
PS_ADAPTER_ODPROXY = ODProxy(_v721.build(address(this)));
}

Expand Down Expand Up @@ -135,7 +118,7 @@ contract ParaswapSellAdapter is FlashLoanSimpleReceiverBase, IParaswapSellAdapte
address asset,

Check warning on line 118 in src/leverage/ParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'asset' should start with _
uint256 amount,

Check warning on line 119 in src/leverage/ParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'amount' should start with _
uint256 premium,

Check warning on line 120 in src/leverage/ParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'premium' should start with _
address initiator,
address, /* initiator */
bytes calldata params

Check warning on line 122 in src/leverage/ParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

'params' should start with _
) external override returns (bool) {
(uint256 _minDstAmount, SellParams memory _sellParams, bytes memory _payload) =
Expand Down Expand Up @@ -182,6 +165,14 @@ contract ParaswapSellAdapter is FlashLoanSimpleReceiverBase, IParaswapSellAdapte
_deposits[_account][_asset] = _amount;
}

/// @dev transfer asset to this owner
function _withdraw(address _account, address _asset, uint256 _amount) internal {
uint256 _balance = _deposits[_account][_asset];
if (_balance < _amount) revert();
_deposits[_account][_asset] = _balance - _amount;
IERC20Metadata(_asset).transferFrom(address(this), _account, _amount);
}

/// @dev takes ParaSwap transaction data and executes sell swap
function _sellOnParaSwap(
uint256 _offset,
Expand Down
19 changes: 19 additions & 0 deletions src/leverage/interfaces/IParaswapSellAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ pragma solidity 0.8.20;
import {IPoolAddressesProvider} from '@aave-core-v3/contracts/interfaces/IPoolAddressesProvider.sol';

Check warning on line 4 in src/leverage/interfaces/IParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

imported name IPoolAddressesProvider is not used
import {IPool} from '@aave-core-v3/contracts/interfaces/IPool.sol';

Check warning on line 5 in src/leverage/interfaces/IParaswapSellAdapter.sol

View workflow job for this annotation

GitHub Actions / Run Linters (18.x)

imported name IPool is not used

/**
* _augustusRegistry address of Paraswap AugustusRegistry
* _augustusSwapper address of Paraswap AugustusSwapper
* _poolProvider address of Aave PoolAddressProvider
* _vault721 address of OpenDollar Vault721
* _exitActions address of OpenDollar ExitActions
* _collateralJoinFactory address of OpenDollar CollateralJoinFactory
* _coinJoin address of OpenDollar CoinJoin
*/
struct InitSellAdapter {
address augustusRegistry;
address augustusSwapper;
address poolProvider;
address vault721;
address exitActions;
address collateralJoinFactory;
address coinJoin;
}

interface IParaswapSellAdapter {
/**
* @dev emitted after a sell of an asset is made
Expand Down
19 changes: 14 additions & 5 deletions test/e2e/E2ESwapExit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {IERC20Metadata} from '@openzeppelin/token/ERC20/extensions/IERC20Metadat
import {IVault721} from '@opendollar/interfaces/proxies/IVault721.sol';
import {IDenominatedOracle} from '@opendollar/interfaces/oracles/IDenominatedOracle.sol';
import {AugustusRegistry} from '@aave-debt-swap/dependencies/paraswap/AugustusRegistry.sol';
import {ParaswapSellAdapter, IParaswapSellAdapter} from 'src/leverage/ParaswapSellAdapter.sol';
import {ParaswapSellAdapter, IParaswapSellAdapter, InitSellAdapter} from 'src/leverage/ParaswapSellAdapter.sol';
import {CommonTest} from 'test/e2e/common/CommonTest.t.sol';
import {Math} from '@opendollar/libraries/Math.sol';

Expand Down Expand Up @@ -44,8 +44,7 @@ contract E2ESwapExit is CommonTest {

userNFV = vault721.getNfvState(vaults[userProxy]);

sellAdapter = new ParaswapSellAdapter(
address(systemCoin),
InitSellAdapter memory _init = InitSellAdapter(
AugustusRegistry.ARBITRUM,
PARASWAP_AUGUSTUS_SWAPPER,
AAVE_POOL_ADDRESS_PROVIDER,
Expand All @@ -55,6 +54,8 @@ contract E2ESwapExit is CommonTest {
address(coinJoin)
);

sellAdapter = new ParaswapSellAdapter(_init);

SELL_ADAPTER = address(sellAdapter);

sellAdapterProxy = _deployOrFind(SELL_ADAPTER);
Expand Down Expand Up @@ -107,7 +108,7 @@ contract E2ESwapExit is CommonTest {
function testRequestFlashloan4() public {
uint256 _initCapital = 10 ether;

/// @notice locked 55% collateral independently from capital allocated to leverage (swap loss?)
/// @notice locked 60% collateral independently from capital allocated to leverage (swap loss?)
uint256 _additionalCapital = _initCapital * 60 / 100;

_testRequestFlashLoan(_initCapital, _additionalCapital);
Expand All @@ -119,7 +120,7 @@ contract E2ESwapExit is CommonTest {

// 100 / 1.35% = 74
uint256 _percentMaxDebt = uint256(10_000) / uint256(135);
emit log_named_uint('_percentMaxDebt ', _percentMaxDebt);
emit log_named_uint('_percentMaxDebt ', _percentMaxDebt);

// 100 - 74 = 26
uint256 _percentMakeUp = 100 - _percentMaxDebt;
Expand Down Expand Up @@ -155,6 +156,14 @@ contract E2ESwapExit is CommonTest {
uint256 _deposit = _initCapital + _additionalCapital;
deal(RETH_ADDR, USER, _deposit);

/**
* todo: 2 sdk calls to dynamically calculate
* 1. max leverage
* 2. sdk call to get slippage
* 3. recalculate max leverage w/ slippage
* 4. sdk get tx
* 5. call smart contract for Aave loan
*/
uint256 _maxLoan = _calculateMaxLeverage(_initCapital, 135);
uint256 _sellAmount = _maxLoan.wmul(rethUsdPrice);
emit log_named_uint('DEBT SELL AMOUNT', _sellAmount);
Expand Down
8 changes: 5 additions & 3 deletions test/e2e/E2ESwapSell.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity 0.8.20;

import '@script/Registry.s.sol';
import {AugustusRegistry} from '@aave-debt-swap/dependencies/paraswap/AugustusRegistry.sol';
import {ParaswapSellAdapter, IParaswapSellAdapter} from 'src/leverage/ParaswapSellAdapter.sol';
import {ParaswapSellAdapter, IParaswapSellAdapter, InitSellAdapter} from 'src/leverage/ParaswapSellAdapter.sol';
import {BaseTest} from 'test/e2e/common/BaseTest.t.sol';
import {BytesLib} from 'src/library/BytesLib.sol';

Expand All @@ -12,8 +12,8 @@ contract E2ESwapSell is BaseTest {

function setUp() public virtual {
vm.createSelectFork(vm.rpcUrl('mainnet'));
sellAdapter = new ParaswapSellAdapter(
address(0xaaa),

InitSellAdapter memory _init = InitSellAdapter(
AugustusRegistry.ARBITRUM,
PARASWAP_AUGUSTUS_SWAPPER,
AAVE_POOL_ADDRESS_PROVIDER,
Expand All @@ -22,6 +22,8 @@ contract E2ESwapSell is BaseTest {
address(0x456),
address(0x789)
);

sellAdapter = new ParaswapSellAdapter(_init);
}

function testSwapRethToWeth() public {
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/common/BaseTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ contract BaseTest is Test {
) internal returns (bytes memory _result) {
string[] memory inputs = new string[](8);
inputs[0] = 'node';
inputs[1] = './script/getSwapRoute.js';
inputs[1] = './script/getSwapTransaction.js';
inputs[2] = vm.toString(_fromToken);
inputs[3] = vm.toString(_fromDecimals);
inputs[4] = vm.toString(_toToken);
Expand Down
7 changes: 2 additions & 5 deletions test/e2e/common/CommonTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ contract CommonTest is Common, BaseTest {
ExitActions public exitActions;
LeverageCalculator public leverageCalculator;

mapping(address proxy => uint256 safeId) public vaults;

function setUp() public virtual override {
_isCastTokens = true;
super.setUp();
// todo: enable systemCoin on Mainnet feature
// useCoin = true
exitActions = new ExitActions();
leverageCalculator = new LeverageCalculator(address(vault721));
token = address(collateral[TKN]);
Expand All @@ -44,7 +41,7 @@ contract CommonTest is Common, BaseTest {
oracleRelayer.updateCollateralPrice(_cType);
}

function _readCTypePrice(bytes32 _cType) internal returns (uint256 _price) {
function _readCTypePrice(bytes32 _cType) internal view returns (uint256 _price) {
_price = delayedOracle[_cType].read();
}

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,10 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"

"@opendollar/contracts@0.0.0-984c17c2":
version "0.0.0-984c17c2"
resolved "https://registry.yarnpkg.com/@opendollar/contracts/-/contracts-0.0.0-984c17c2.tgz#52a03256654cc7fe69cff430d60bed07d9a8648a"
integrity sha512-4AV3GKyi+deaSq1jsSUSP22/hkywYhF0EOE2v7cq7MnK3fuSKOSChKmLO0Hx/1PrRxhoE3/eIxqQuaPEqhpt0A==
"@opendollar/contracts@0.0.0-161d9907":
version "0.0.0-161d9907"
resolved "https://registry.yarnpkg.com/@opendollar/contracts/-/contracts-0.0.0-161d9907.tgz#188299a503fbf7115f9fdbde63d27a3ab7a12ed2"
integrity sha512-VL4crtfR4U9hrdneytWwJfvummB/D9K/3dNQGYX1dmvtBR1x1d47m6tUAneQuvvxzp1ifm2pOPiE78UQI4jnSw==
dependencies:
"@defi-wonderland/solidity-utils" "0.0.0-4298c6c6"
"@openzeppelin/contracts" "4.9.6"
Expand Down

0 comments on commit 6134c56

Please sign in to comment.