Contract 0x333733DEedd11Ee40D41Df7b0327bBB57397a1CA 1

Txn Hash Method
Block
From
To
Value [Txn Fee]
0x5433f925cdf8cb75f92a3bba4ccb5fc038197864f970a6445cc45cdd6b005aaf0x6080604076778292021-12-01 18:39:1456 days 13 hrs ago0xa9061100d29c3c562a2e2421eb035741c1b42137 IN  Create: InstaFlashloanResolverAvalanche0 AVAX0.0484467030640.11
[ Download CSV Export 
Parent Txn Hash Block From To Value
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
InstaFlashloanResolverAvalanche

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 5 : main.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { Helper } from "./helpers.sol";

import { 
    InstaFlashloanAggregatorInterface
} from "./interfaces.sol";

contract FlashResolverAvalanche is Helper {
    function getRoutesInfo() public view returns (uint16[] memory routes_, uint256[] memory fees_) {
        routes_ = flashloanAggregator.getRoutes();
        fees_ = new uint256[](routes_.length);
        for(uint256 i = 0; i < routes_.length; i++) {
            fees_[i] = flashloanAggregator.calculateFeeBPS(routes_[i]);
        }
    }

    function getBestRoutes(address[] memory _tokens, uint256[] memory _amounts) public view returns (uint16[] memory, uint256) {
        require(_tokens.length == _amounts.length, "array-lengths-not-same");

        (_tokens, _amounts) = bubbleSort(_tokens, _amounts);
        validateTokens(_tokens);
        
        uint16[] memory bRoutes_;
        uint256 feeBPS_;
        uint16[] memory routes_ = flashloanAggregator.getRoutes();
        uint16[] memory routesWithAvailability_ = getRoutesWithAvailability(routes_, _tokens, _amounts);
        uint16 j = 0;
        bRoutes_ = new uint16[](routes_.length);
        feeBPS_ = type(uint256).max;
        for(uint256 i = 0; i < routesWithAvailability_.length; i++) {
            if(routesWithAvailability_[i] != 0) {
                uint routeFeeBPS_ = flashloanAggregator.calculateFeeBPS(routesWithAvailability_[i]);
                if(feeBPS_ > routeFeeBPS_) {
                    feeBPS_ = routeFeeBPS_;
                    bRoutes_[0] = routesWithAvailability_[i];
                    j=1;
                } else if (feeBPS_ == routeFeeBPS_) {
                    bRoutes_[j] = routesWithAvailability_[i];
                    j++;
                }
            } 
        }
        uint16[] memory bestRoutes_ = new uint16[](j);
        for(uint256 i = 0; i < j ; i++) {
            bestRoutes_[i] = bRoutes_[i];
        }
        return (bestRoutes_, feeBPS_);
    }

    function getData(address[] memory _tokens, uint256[] memory _amounts) public view returns (uint16[] memory routes_, uint256[] memory fees_, uint16[] memory bestRoutes_, uint256 bestFee_) {
        (routes_, fees_) = getRoutesInfo();
        (bestRoutes_, bestFee_) = getBestRoutes(_tokens, _amounts);
        return (routes_, fees_, bestRoutes_, bestFee_);
    }
    
}

contract InstaFlashloanResolverAvalanche is FlashResolverAvalanche {
    receive() external payable {}
}

File 2 of 5 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 3 of 5 : helpers.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

import {Variables} from "./variables.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract Helper is Variables {
    function getAaveAvailability(address[] memory  _tokens, uint256[] memory  _amounts) internal view returns (bool) {
        for(uint256 i = 0; i < _tokens.length; i++) {
            IERC20 token_ = IERC20(_tokens[i]);
            (,,,,,,,,bool isActive,) = aaveProtocolDataProvider.getReserveConfigurationData(_tokens[i]);
            (address aTokenAddr,,) = aaveProtocolDataProvider.getReserveTokensAddresses(_tokens[i]);
            if(isActive == false) return false;
            if(token_.balanceOf(aTokenAddr) < _amounts[i]) return false;
        }
        return true;
    }

    function getRoutesWithAvailability(uint16[] memory _routes, address[] memory _tokens, uint256[] memory _amounts) internal view returns (uint16[] memory) {
        uint16[] memory routesWithAvailability_ = new uint16[](7);
        uint j = 0;
        for(uint256 i = 0; i < _routes.length; i++) {
            if (_routes[i] == 1) {
                if(getAaveAvailability(_tokens, _amounts)) {
                    routesWithAvailability_[j] = _routes[i];
                    j++;
                }
            } else {
                require(false, "invalid-route");
            }
        }
        return routesWithAvailability_;
    }

    function bubbleSort(address[] memory _tokens, uint256[] memory _amounts) internal pure returns (address[] memory, uint256[] memory) {
        for (uint256 i = 0; i < _tokens.length - 1; i++) {
            for( uint256 j = 0; j < _tokens.length - i - 1 ; j++) {
                if(_tokens[j] > _tokens[j+1]) {
                    (_tokens[j], _tokens[j+1], _amounts[j], _amounts[j+1]) = (_tokens[j+1], _tokens[j], _amounts[j+1], _amounts[j]);
                }
            }
        }
        return (_tokens, _amounts);
    }

    function validateTokens(address[] memory _tokens) internal pure {
        for (uint i = 0; i < _tokens.length - 1; i++) {
            require(_tokens[i] != _tokens[i+1], "non-unique-tokens");
        }
    }
}

File 4 of 5 : interfaces.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

interface InstaFlashloanAggregatorInterface {
    function getRoutes() external pure returns (uint16[] memory);
    function calculateFeeBPS(uint256 _route) external view returns (uint256);
}

interface IAaveProtocolDataProvider {
    function getReserveConfigurationData(address asset) external view returns (uint256, uint256, uint256, uint256, uint256, bool, bool, bool, bool, bool);
    function getReserveTokensAddresses(address asset) external view returns (address, address, address);
}

File 5 of 5 : variables.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;


import { 
    InstaFlashloanAggregatorInterface,
    IAaveProtocolDataProvider
} from "./interfaces.sol";

contract Variables {

    address public constant aaveLendingAddr = 0x4F01AeD16D97E3aB5ab2B501154DC9bb0F1A5A2C;
    address public constant aaveProtocolDataProviderAddr = 0x65285E9dfab318f57051ab2b139ccCf232945451;
    IAaveProtocolDataProvider public constant aaveProtocolDataProvider = IAaveProtocolDataProvider(aaveProtocolDataProviderAddr);

    address private flashloanAggregatorAddr = 0x2b65731A085B55DBe6c7DcC8D717Ac36c00F6d19;
    InstaFlashloanAggregatorInterface internal flashloanAggregator = InstaFlashloanAggregatorInterface(flashloanAggregatorAddr);


}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[],"name":"aaveLendingAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveProtocolDataProvider","outputs":[{"internalType":"contract IAaveProtocolDataProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"aaveProtocolDataProviderAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"getBestRoutes","outputs":[{"internalType":"uint16[]","name":"","type":"uint16[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tokens","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"getData","outputs":[{"internalType":"uint16[]","name":"routes_","type":"uint16[]"},{"internalType":"uint256[]","name":"fees_","type":"uint256[]"},{"internalType":"uint16[]","name":"bestRoutes_","type":"uint16[]"},{"internalType":"uint256","name":"bestFee_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRoutesInfo","outputs":[{"internalType":"uint16[]","name":"routes_","type":"uint16[]"},{"internalType":"uint256[]","name":"fees_","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260008054732b65731a085b55dbe6c7dcc8d717ac36c00f6d196001600160a01b0319918216811790925560018054909116909117905534801561004657600080fd5b50611417806100566000396000f3fe6080604052600436106100695760003560e01c80635f9d4d2e116100435780635f9d4d2e146100ff578063dac4e0e9146100ff578063f33651531461013f57600080fd5b80631f3f6ff91461007557806337b0df58146100ac5780635ccaebad146100dc57600080fd5b3661007057005b600080fd5b34801561008157600080fd5b50610095610090366004610fea565b610167565b6040516100a39291906112e3565b60405180910390f35b3480156100b857600080fd5b506100cc6100c7366004610fea565b6105ad565b6040516100a39493929190611298565b3480156100e857600080fd5b506100f16105d6565b6040516100a392919061126a565b34801561010b57600080fd5b506101277365285e9dfab318f57051ab2b139cccf23294545181565b6040516001600160a01b0390911681526020016100a3565b34801561014b57600080fd5b50610127734f01aed16d97e3ab5ab2b501154dc9bb0f1a5a2c81565b6060600082518451146101c15760405162461bcd60e51b815260206004820152601660248201527f61727261792d6c656e677468732d6e6f742d73616d650000000000000000000060448201526064015b60405180910390fd5b6101cb84846107bc565b90945092506101d984610a22565b6060600080600160009054906101000a90046001600160a01b03166001600160a01b0316637e9280726040518163ffffffff1660e01b815260040160006040518083038186803b15801561022c57600080fd5b505afa158015610240573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261026891908101906110ad565b90506000610277828989610b0a565b90506000825167ffffffffffffffff8111156102a357634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156102cc578160200160208202803683370190505b509450600019935060005b82518110156104c75782818151811061030057634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff166000146104b55760015483516000916001600160a01b03169063426bfa4d9086908590811061034b57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610379919061ffff91909116815260200190565b60206040518083038186803b15801561039157600080fd5b505afa1580156103a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c9919061114f565b90508086111561043e578095508382815181106103f657634e487b7160e01b600052603260045260246000fd5b60200260200101518760008151811061041f57634e487b7160e01b600052603260045260246000fd5b602002602001019061ffff16908161ffff1681525050600192506104b3565b808614156104b35783828151811061046657634e487b7160e01b600052603260045260246000fd5b6020026020010151878461ffff168151811061049257634e487b7160e01b600052603260045260246000fd5b61ffff90921660209283029190910190910152826104af81611389565b9350505b505b806104bf816113ab565b9150506102d7565b5060008161ffff1667ffffffffffffffff8111156104f557634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561051e578160200160208202803683370190505b50905060005b8261ffff1681101561059d5786818151811061055057634e487b7160e01b600052603260045260246000fd5b602002602001015182828151811061057857634e487b7160e01b600052603260045260246000fd5b61ffff9092166020928302919091019091015280610595816113ab565b915050610524565b5099939850929650505050505050565b606080606060006105bc6105d6565b90945092506105cb8686610167565b949793965094505050565b606080600160009054906101000a90046001600160a01b03166001600160a01b0316637e9280726040518163ffffffff1660e01b815260040160006040518083038186803b15801561062757600080fd5b505afa15801561063b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261066391908101906110ad565b9150815167ffffffffffffffff81111561068d57634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156106b6578160200160208202803683370190505b50905060005b82518110156107b75760015483516001600160a01b039091169063426bfa4d908590849081106106fc57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161072a919061ffff91909116815260200190565b60206040518083038186803b15801561074257600080fd5b505afa158015610756573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077a919061114f565b82828151811061079a57634e487b7160e01b600052603260045260246000fd5b6020908102919091010152806107af816113ab565b9150506106bc565b509091565b60608060005b600185516107d09190611372565b811015610a195760005b60018287516107e99190611372565b6107f39190611372565b811015610a06578561080682600161135a565b8151811061082457634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031686828151811061085557634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b031611156109f4578561087882600161135a565b8151811061089657634e487b7160e01b600052603260045260246000fd5b60200260200101518682815181106108be57634e487b7160e01b600052603260045260246000fd5b6020026020010151868360016108d4919061135a565b815181106108f257634e487b7160e01b600052603260045260246000fd5b602002602001015187848151811061091a57634e487b7160e01b600052603260045260246000fd5b602002602001015189858151811061094257634e487b7160e01b600052603260045260246000fd5b602002602001018a866001610957919061135a565b8151811061097557634e487b7160e01b600052603260045260246000fd5b602002602001018a878151811061099c57634e487b7160e01b600052603260045260246000fd5b602002602001018b8860016109b1919061135a565b815181106109cf57634e487b7160e01b600052603260045260246000fd5b6020908102919091010193909352929091526001600160a01b03928316909152911690525b806109fe816113ab565b9150506107da565b5080610a11816113ab565b9150506107c2565b50929391925050565b60005b60018251610a339190611372565b811015610b065781610a4682600161135a565b81518110610a6457634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316828281518110610a9557634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03161415610af45760405162461bcd60e51b815260206004820152601160248201527f6e6f6e2d756e697175652d746f6b656e7300000000000000000000000000000060448201526064016101b8565b80610afe816113ab565b915050610a25565b5050565b6040805160078082526101008201909252606091600091906020820160e0803683370190505090506000805b8651811015610c4a57868181518110610b5f57634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff1660011415610bf057610b7d8686610c55565b15610beb57868181518110610ba257634e487b7160e01b600052603260045260246000fd5b6020026020010151838381518110610bca57634e487b7160e01b600052603260045260246000fd5b61ffff9092166020928302919091019091015281610be7816113ab565b9250505b610c38565b60405162461bcd60e51b815260206004820152600d60248201527f696e76616c69642d726f7574650000000000000000000000000000000000000060448201526064016101b8565b80610c42816113ab565b915050610b36565b509095945050505050565b6000805b8351811015610f0e576000848281518110610c8457634e487b7160e01b600052603260045260246000fd5b6020026020010151905060007365285e9dfab318f57051ab2b139cccf2329454516001600160a01b0316633e150141878581518110610cd357634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610d0691906001600160a01b0391909116815260200190565b6101406040518083038186803b158015610d1f57600080fd5b505afa158015610d33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d579190611167565b509850505050505050505060007365285e9dfab318f57051ab2b139cccf2329454516001600160a01b031663d2493b6c888681518110610da757634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610dda91906001600160a01b0391909116815260200190565b60606040518083038186803b158015610df257600080fd5b505afa158015610e06573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2a9190610f9e565b509091505081610e41576000945050505050610f14565b858481518110610e6157634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516370a0823160e01b81526001600160a01b0383811660048301528516906370a082319060240160206040518083038186803b158015610ead57600080fd5b505afa158015610ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee5919061114f565b1015610ef8576000945050505050610f14565b5050508080610f06906113ab565b915050610c59565b50600190505b92915050565b600082601f830112610f2a578081fd5b81356020610f3f610f3a83611336565b611305565b80838252828201915082860187848660051b8901011115610f5e578586fd5b855b85811015610f7c57813584529284019290840190600101610f60565b5090979650505050505050565b80518015158114610f9957600080fd5b919050565b600080600060608486031215610fb2578283fd5b8351610fbd816113f2565b6020850151909350610fce816113f2565b6040850151909250610fdf816113f2565b809150509250925092565b60008060408385031215610ffc578182fd5b823567ffffffffffffffff80821115611013578384fd5b818501915085601f830112611026578384fd5b81356020611036610f3a83611336565b8083825282820191508286018a848660051b8901011115611055578889fd5b8896505b8487101561108057803561106c816113f2565b835260019690960195918301918301611059565b5096505086013592505080821115611096578283fd5b506110a385828601610f1a565b9150509250929050565b600060208083850312156110bf578182fd5b825167ffffffffffffffff8111156110d5578283fd5b8301601f810185136110e5578283fd5b80516110f3610f3a82611336565b80828252848201915084840188868560051b8701011115611112578687fd5b8694505b8385101561114357805161ffff8116811461112f578788fd5b835260019490940193918501918501611116565b50979650505050505050565b600060208284031215611160578081fd5b5051919050565b6000806000806000806000806000806101408b8d031215611186578586fd5b8a51995060208b0151985060408b0151975060608b0151965060808b015195506111b260a08c01610f89565b94506111c060c08c01610f89565b93506111ce60e08c01610f89565b92506111dd6101008c01610f89565b91506111ec6101208c01610f89565b90509295989b9194979a5092959850565b6000815180845260208085019450808401835b8381101561123057815161ffff1687529582019590820190600101611210565b509495945050505050565b6000815180845260208085019450808401835b838110156112305781518752958201959082019060010161124e565b60408152600061127d60408301856111fd565b828103602084015261128f818561123b565b95945050505050565b6080815260006112ab60808301876111fd565b82810360208401526112bd818761123b565b905082810360408401526112d181866111fd565b91505082606083015295945050505050565b6040815260006112f660408301856111fd565b90508260208301529392505050565b604051601f8201601f1916810167ffffffffffffffff8111828210171561132e5761132e6113dc565b604052919050565b600067ffffffffffffffff821115611350576113506113dc565b5060051b60200190565b6000821982111561136d5761136d6113c6565b500190565b600082821015611384576113846113c6565b500390565b600061ffff808316818114156113a1576113a16113c6565b6001019392505050565b60006000198214156113bf576113bf6113c6565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461140757600080fd5b5056fea164736f6c6343000804000a

Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.