Skip to content

Commit

Permalink
Merge pull request #75 from Instadapp/fantom-support-changes
Browse files Browse the repository at this point in the history
Fantom Refactored code
  • Loading branch information
shriyatyagii authored Jul 5, 2022
2 parents f88e19f + 04fe872 commit 6b2c8f3
Show file tree
Hide file tree
Showing 10 changed files with 201 additions and 170 deletions.
105 changes: 44 additions & 61 deletions contracts/aggregator/fantom/flashloan/helper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pragma solidity ^0.8.0;
import "../../../common/helpers.sol";
import "./variable.sol";

contract Helper is Variables, HelpersCommon {
contract Helper is Variables, TokenHelpers, FlashloanHelpers {
using SafeERC20 for IERC20;

/**
Expand All @@ -15,77 +15,60 @@ contract Helper is Variables, HelpersCommon {
return instaList.accountID(_account) > 0;
}

/**
* @dev Approves the tokens to the receiver address with allowance (amount + fee).
* @notice Approves the tokens to the receiver address with allowance (amount + fee).
* @param _instaLoanVariables struct which includes list of token addresses and amounts.
* @param _fees list of premiums/fees for the corresponding addresses for flashloan.
* @param _receiver address to which tokens have to be approved.
/**
* @dev Returns fee for the passed route in BPS.
* @notice Returns fee for the passed route in BPS. 1 BPS == 0.01%.
* @param _route route number for flashloan.
*/
function safeApprove(
FlashloanVariables memory _instaLoanVariables,
uint256[] memory _fees,
address _receiver
) internal {
uint256 length_ = _instaLoanVariables._tokens.length;
require(length_ == _instaLoanVariables._amounts.length, 'Lengths of parameters not same');
require(length_ == _fees.length, 'Lengths of parameters not same');
for (uint256 i = 0; i < length_; i++) {
approve(_instaLoanVariables._tokens[i], _receiver, _instaLoanVariables._amounts[i] + _fees[i]);
}
function calculateFeeBPS(uint256 _route)
public
view
virtual
returns (uint256 BPS_)
{
bytes memory _output = Address.functionStaticCall(
routeToImplementation[_route],
msg.data,
"calculateFeeBPS-call-failed"
);
BPS_ = abi.decode(_output, (uint256));
}

/**
* @dev Transfers the tokens to the receiver address.
* @notice Transfers the tokens to the receiver address.
* @param _instaLoanVariables struct which includes list of token addresses and amounts.
* @param _receiver address to which tokens have to be transferred.
* @dev Function to get the list of all routes.
* @notice Function to get the list of all routes.
*/
function safeTransfer(FlashloanVariables memory _instaLoanVariables, address _receiver) internal {
uint256 length_ = _instaLoanVariables._tokens.length;
require(length_ == _instaLoanVariables._amounts.length, 'Lengths of parameters not same');
for (uint256 i = 0; i < length_; i++) {
IERC20 token = IERC20(_instaLoanVariables._tokens[i]);
token.safeTransfer(_receiver, _instaLoanVariables._amounts[i]);
}
function getRoutes() public view returns (uint256[] memory) {
return routes;
}

/**
* @dev Validates if the receiver sent the correct amounts of funds.
* @notice Validates if the receiver sent the correct amounts of funds.
* @param _instaLoanVariables struct which includes list of initial balances, final balances and fees for the respective tokens.
* @dev Function to get the list of enabled routes.
* @notice Function to get the list of enabled routes.
*/
function validateFlashloan(FlashloanVariables memory _instaLoanVariables) internal pure {
for (uint256 i = 0; i < _instaLoanVariables._iniBals.length; i++) {
require(
_instaLoanVariables._iniBals[i] + _instaLoanVariables._instaFees[i] <= _instaLoanVariables._finBals[i],
'amount-paid-less'
);
function getEnabledRoutes()
public
view
returns (uint16[] memory routesEnabled_)
{
uint256[] memory routesAll_ = getRoutes();
uint256 length = routesAll_.length;
uint256 _count = 0;

for (uint256 i = 0; i < length; i++) {
if (routeStatus[routesAll_[i]] == true) {
_count++;
}
}
}

/**
* @dev better checking by double encoding the data.
* @notice better checking by double encoding the data.
* @param data_ data passed.
*/
modifier verifyDataHash(bytes memory data_) {
bytes32 dataHash_ = keccak256(data_);
require(dataHash_ == dataHash && dataHash_ != bytes32(0), 'invalid-data-hash');
require(status == 2, 'already-entered');
dataHash = bytes32(0);
_;
status = 1;
}
routesEnabled_ = new uint16[](_count);
uint256 k = 0;

/**
* @dev reentrancy gaurd.
* @notice reentrancy gaurd.
*/
modifier reentrancy() {
require(status == 1, 'already-entered');
status = 2;
_;
require(status == 1, 'already-entered');
for (uint256 j = 0; j < length; j++) {
if (routeStatus[routesAll_[j]]) {
routesEnabled_[k] = uint16(routesAll_[j]);
k++;
}
}
}
}
12 changes: 1 addition & 11 deletions contracts/aggregator/fantom/flashloan/main.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "./helper.sol";
import "../../../common/main.sol";

/**
* @title Flashloan.
Expand All @@ -20,15 +19,6 @@ contract AdminModule is Helper {

event LogCollectRevenue(address to, address[] tokens, uint256[] amounts);

/**
* @dev owner gaurd.
* @notice owner gaurd.
*/
modifier onlyOwner() {
require(msg.sender == owner, "not-owner");
_;
}

/**
* @dev Update owner.
* @notice Update owner.
Expand Down Expand Up @@ -146,7 +136,7 @@ contract AdminModule is Helper {
}
}

contract FlashAggregatorFantom is FlashloanAggregator, AdminModule {
contract FlashAggregatorFantom is AdminModule {
event LogFlashloan(address indexed account, uint256 indexed route, address[] tokens, uint256[] amounts);

/**
Expand Down
5 changes: 3 additions & 2 deletions contracts/aggregator/fantom/flashloan/routes/aaveV3/main.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ interface IAaveV3Lending {
function FLASHLOAN_PREMIUM_TOTAL() external view returns (uint128);
}

contract AaveV3Variables {
contract AaveV3ConstantVariables {
address public constant aaveV3LendingAddr =
0x794a61358D6845594F94dc1DB02A252b5b4814aD;
IAaveV3Lending public constant aaveV3Lending =
IAaveV3Lending(aaveV3LendingAddr);
}

contract AaveImplementationFantom is Helper, AaveV3Variables {
contract AaveV3RouteImplementationFantom is AaveV3ConstantVariables, Helper {
/**
* @dev Main function for flashloan for all routes. Calls the middle functions according to routes.
* @notice Main function for flashloan for all routes. Calls the middle functions according to routes.
Expand Down Expand Up @@ -53,6 +53,7 @@ contract AaveImplementationFantom is Helper, AaveV3Variables {
function calculateFeeBPS(uint256 _route)
public
view
override
returns (uint256 BPS_)
{
if (_route == 9) {
Expand Down
1 change: 1 addition & 0 deletions contracts/aggregator/fantom/flashloan/routes/fla/main.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ contract FLAImplementationFantom is Helper {
function calculateFeeBPS(uint256 _route)
public
view
override
returns (uint256 BPS_)
{
if (_route == 10) {
Expand Down
53 changes: 39 additions & 14 deletions contracts/aggregator/fantom/flashloan/variable.sol
Original file line number Diff line number Diff line change
@@ -1,26 +1,51 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "../../../common/variables.sol";

import "../../../common/interfaces.sol";
import "../../../common/variablesV1.sol";
import "../../../common/variablesV2.sol";
import "../../../common/structs.sol";

contract ConstantVariables {
address public constant treasuryAddr =
0x6C4061A00F8739d528b185CC683B6400E0cd396a;
ListInterface public constant instaList = ListInterface(0x10e166c3FAF887D8a61dE6c25039231eE694E926);
uint256 public constant InstaFeeBPS = 5; // in BPS; 1 BPS = 0.01%
}

contract Variables is ConstantVariables {

bytes32 internal dataHash;
// if 1 then can enter flashlaon, if 2 then callback
uint256 internal status;
contract FantomVariablesV1 {
address public owner;

struct FlashloanVariables {
address[] _tokens;
uint256[] _amounts;
uint256[] _iniBals;
uint256[] _finBals;
uint256[] _instaFees;
/**
* @dev owner gaurd.
* @notice owner gaurd.
*/
modifier onlyOwner() {
require(msg.sender == owner, "not-owner");
_;
}

address public owner;
}

contract Variables is ConstantVariables, CommonVariablesV1, Structs, FantomVariablesV1, CommonVariablesV2 {
// ******** Stroage Variable layout ******* //

/* CommonVariablesV1
// bytes32 internal dataHash;
// uint256 internal status;
*/

/* Structs
FlashloanVariables;
*/

/* FantomVariablesV1
// address public owner;
*/

/* CommonVariablesV2
// mapping(uint256 => address) public routeToImplementation;
// mapping(uint256 => bool) public routeStatus;
// address internal fallbackImplementation;
// uint256[] public routes;
*/
}
76 changes: 65 additions & 11 deletions contracts/common/helpers.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
pragma solidity ^0.8.0;

import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import './variables.sol';
import "./interfaces.sol";
import "./variablesV2.sol";
import "./structs.sol";

contract HelpersCommon is VariablesCommon {
contract TokenHelpers is Structs {
using SafeERC20 for IERC20;

/**
Expand Down Expand Up @@ -54,6 +56,56 @@ contract HelpersCommon is VariablesCommon {
}
}

/**
* @dev Sort the tokens and amounts arrays according to token addresses.
* @notice Sort the tokens and amounts arrays according to token addresses.
* @param _token0 address of token0.
* @param _token1 address of token1.
*/
function sortTokens(address _token0, address _token1) internal pure returns (address, address) {
if (_token1 < _token0) {
(_token0, _token1) = (_token1, _token0);
}
return (_token0, _token1);
}

/**
* @dev Approves the tokens to the receiver address with allowance (amount + fee).
* @notice Approves the tokens to the receiver address with allowance (amount + fee).
* @param _instaLoanVariables struct which includes list of token addresses and amounts.
* @param _fees list of premiums/fees for the corresponding addresses for flashloan.
* @param _receiver address to which tokens have to be approved.
*/
function safeApprove(
FlashloanVariables memory _instaLoanVariables,
uint256[] memory _fees,
address _receiver
) internal {
uint256 length_ = _instaLoanVariables._tokens.length;
require(length_ == _instaLoanVariables._amounts.length, 'Lengths of parameters not same');
require(length_ == _fees.length, 'Lengths of parameters not same');
for (uint256 i = 0; i < length_; i++) {
approve(_instaLoanVariables._tokens[i], _receiver, _instaLoanVariables._amounts[i] + _fees[i]);
}
}

/**
* @dev Transfers the tokens to the receiver address.
* @notice Transfers the tokens to the receiver address.
* @param _instaLoanVariables struct which includes list of token addresses and amounts.
* @param _receiver address to which tokens have to be transferred.
*/
function safeTransfer(FlashloanVariables memory _instaLoanVariables, address _receiver) internal {
uint256 length_ = _instaLoanVariables._tokens.length;
require(length_ == _instaLoanVariables._amounts.length, 'Lengths of parameters not same');
for (uint256 i = 0; i < length_; i++) {
IERC20 token = IERC20(_instaLoanVariables._tokens[i]);
token.safeTransfer(_receiver, _instaLoanVariables._amounts[i]);
}
}
}

contract FlashloanHelpers is Structs {
/**
* @dev Calculate fees for the respective amounts and fee in BPS passed.
* @notice Calculate fees for the respective amounts and fee in BPS passed. 1 BPS == 0.01%.
Expand Down Expand Up @@ -95,16 +147,18 @@ contract HelpersCommon is VariablesCommon {
return (_tokens, _amounts);
}


/**
* @dev Sort the tokens and amounts arrays according to token addresses.
* @notice Sort the tokens and amounts arrays according to token addresses.
* @param _token0 address of token0.
* @param _token1 address of token1.
* @dev Validates if the receiver sent the correct amounts of funds.
* @notice Validates if the receiver sent the correct amounts of funds.
* @param _instaLoanVariables struct which includes list of initial balances, final balances and fees for the respective tokens.
*/
function sortTokens(address _token0, address _token1) internal pure returns (address, address) {
if (_token1 < _token0) {
(_token0, _token1) = (_token1, _token0);
function validateFlashloan(FlashloanVariables memory _instaLoanVariables) internal pure {
for (uint256 i = 0; i < _instaLoanVariables._iniBals.length; i++) {
require(
_instaLoanVariables._iniBals[i] + _instaLoanVariables._instaFees[i] <= _instaLoanVariables._finBals[i],
'amount-paid-less'
);
}
return (_token0, _token1);
}
}
}
Loading

0 comments on commit 6b2c8f3

Please sign in to comment.