Contract
0x94a852f0a21e473078846cf88382dd8d15bd1dfb
1
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x10ecbd6b12a62001b5356cc327a51181e0732334f7ecbae315cf07ed5160a7a7 | Set Fee | 25371565 | 6 days 1 hr ago | 0x813288526ccbfade7aba8836a4ca2462eb886bb7 | IN | 0x94a852f0a21e473078846cf88382dd8d15bd1dfb | 0 AVAX | 0.001953756 | |
0xb069f1721e62592fea328003355909e5f85179a29faf4237c5bb7577873209d7 | Set Owner | 25371564 | 6 days 1 hr ago | 0x813288526ccbfade7aba8836a4ca2462eb886bb7 | IN | 0x94a852f0a21e473078846cf88382dd8d15bd1dfb | 0 AVAX | 0.001339856 | |
0x1b7acdf5c390f1cb5697fc59a0bfbaa4e7854f0dde9daf34ac299702c143955c | 0x60806040 | 25371561 | 6 days 1 hr ago | 0x813288526ccbfade7aba8836a4ca2462eb886bb7 | IN | Create: TSAggregatorGeneric | 0 AVAX | 0.020609316 |
[ Download CSV Export ]
Contract Name:
TSAggregatorGeneric
Compiler Version
v0.8.10+commit.fc410830
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Gas optimized reentrancy protection for smart contracts. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/ReentrancyGuard.sol) /// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol) abstract contract ReentrancyGuard { uint256 private locked = 1; modifier nonReentrant() { require(locked == 1, "REENTRANCY"); locked = 2; _; locked = 1; } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/SafeTransferLib.sol) /// @author Modified from Gnosis (https://github.com/gnosis/gp-v2-contracts/blob/main/src/contracts/libraries/GPv2SafeERC20.sol) /// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer. library SafeTransferLib { /*/////////////////////////////////////////////////////////////// ETH OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferETH(address to, uint256 amount) internal { bool callStatus; assembly { // Transfer the ETH and store if it succeeded or not. callStatus := call(gas(), to, amount, 0, 0, 0, 0) } require(callStatus, "ETH_TRANSFER_FAILED"); } /*/////////////////////////////////////////////////////////////// ERC20 OPERATIONS //////////////////////////////////////////////////////////////*/ function safeTransferFrom( address token, address from, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "from" argument. mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 68), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 100 because the calldata length is 4 + 32 * 3. callStatus := call(gas(), token, 0, freeMemoryPointer, 100, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FROM_FAILED"); } function safeTransfer( address token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "TRANSFER_FAILED"); } function safeApprove( address token, address to, uint256 amount ) internal { bool callStatus; assembly { // Get a pointer to some free memory. let freeMemoryPointer := mload(0x40) // Write the abi-encoded calldata to memory piece by piece: mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000) // Begin with the function selector. mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Mask and append the "to" argument. mstore(add(freeMemoryPointer, 36), amount) // Finally append the "amount" argument. No mask as it's a full 32 byte value. // Call the token and store if it succeeded or not. // We use 68 because the calldata length is 4 + 32 * 2. callStatus := call(gas(), token, 0, freeMemoryPointer, 68, 0, 0) } require(didLastOptionalReturnCallSucceed(callStatus), "APPROVE_FAILED"); } /*/////////////////////////////////////////////////////////////// INTERNAL HELPER LOGIC //////////////////////////////////////////////////////////////*/ function didLastOptionalReturnCallSucceed(bool callStatus) private pure returns (bool success) { assembly { // Get how many bytes the call returned. let returnDataSize := returndatasize() // If the call reverted: if iszero(callStatus) { // Copy the revert message into memory. returndatacopy(0, 0, returnDataSize) // Revert with the same message. revert(0, returnDataSize) } switch returnDataSize case 32 { // Copy the return data into memory. returndatacopy(0, 0, returnDataSize) // Set success to whether it returned true. success := iszero(iszero(mload(0))) } case 0 { // There was no return data. success := 1 } default { // It returned some malformed input. success := 0 } } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; abstract contract Owners { event OwnerSet(address indexed owner, bool active); mapping(address => bool) public owners; modifier isOwner() { require(owners[msg.sender], "Unauthorized"); _; } function _setOwner(address owner, bool active) internal virtual { owners[owner] = active; emit OwnerSet(owner, active); } function setOwner(address owner, bool active) external virtual isOwner { _setOwner(owner, active); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import { SafeTransferLib } from "../lib/SafeTransferLib.sol"; import { ReentrancyGuard } from "../lib/ReentrancyGuard.sol"; import { Owners } from "./Owners.sol"; import { TSAggregatorTokenTransferProxy } from './TSAggregatorTokenTransferProxy.sol'; abstract contract TSAggregator is Owners, ReentrancyGuard { using SafeTransferLib for address; event FeeSet(uint256 fee, address feeRecipient); uint256 public fee; address public feeRecipient; TSAggregatorTokenTransferProxy public tokenTransferProxy; constructor(address _tokenTransferProxy) { _setOwner(msg.sender, true); tokenTransferProxy = TSAggregatorTokenTransferProxy(_tokenTransferProxy); } // Needed for the swap router to be able to send back ETH receive() external payable {} function setFee(uint256 _fee, address _feeRecipient) external isOwner { require(_fee <= 1000, "fee can not be more than 10%"); fee = _fee; feeRecipient = _feeRecipient; emit FeeSet(_fee, _feeRecipient); } function skimFee(uint256 amount) internal returns (uint256) { uint256 amountFee = getFee(amount); if (amountFee > 0) { feeRecipient.safeTransferETH(amountFee); amount -= amountFee; } return amount; } function getFee(uint256 amount) internal view returns (uint256) { if (fee != 0 && feeRecipient != address(0)) { return (amount * fee) / 10000; } return 0; } // Parse amountOutMin treating the last 2 digits as an exponent // So 15e4 = 150000. This allows for compressed memos on chains // with limited space like Bitcoin function _parseAmountOutMin(uint256 amount) internal pure returns (uint256) { return amount / 100 * (10 ** (amount % 100)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import { SafeTransferLib } from "../lib/SafeTransferLib.sol"; import { TSAggregator } from "./TSAggregator.sol"; import { IERC20 } from "./interfaces/IERC20.sol"; import { IThorchainRouter } from "./interfaces/IThorchainRouter.sol"; import { TSAggregatorTokenTransferProxy } from './TSAggregatorTokenTransferProxy.sol'; contract TSAggregatorGeneric is TSAggregator { using SafeTransferLib for address; event SwapIn(address from, address token, uint256 amount, uint256 out, uint256 fee, address vault, string memo); constructor(address _ttp) TSAggregator(_ttp) { } // Use 1inch's swap API endpoint to get data to send // e.g. https://api.1inch.io/v4.0/1/swap?toTokenAddress=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&fromTokenAddress=0x111111111117dc0aa78b770fa6a738034120c302&amount=10000000000000000&fromAddress=0x2f8aedd149afbdb5206ecaf8b1a3abb9186c8053&slippage=1&disableEstimate=true // toTokenAddress needs to be 0xeeee so ETH is sent back to swapIn // fromAddress needs to be the address of this contract // disableEstimate makes the API return a result even if there's no token balance in the contract function swapIn( address router, address vault, string calldata memo, address token, uint amount, address swapRouter, bytes calldata data, uint deadline ) public nonReentrant { require(swapRouter != address(tokenTransferProxy), "no calling ttp"); tokenTransferProxy.transferTokens(token, msg.sender, address(this), amount); token.safeApprove(address(swapRouter), 0); // USDT quirk token.safeApprove(address(swapRouter), amount); { (bool success,) = swapRouter.call(data); require(success, "failed to swap"); } uint256 out = address(this).balance; { uint256 outMinusFee = skimFee(out); IThorchainRouter(router).depositWithExpiry{value: outMinusFee}( payable(vault), address(0), outMinusFee, memo, deadline ); } emit SwapIn(msg.sender, token, amount, out+getFee(out), getFee(out), vault, memo); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; import { SafeTransferLib } from "../lib/SafeTransferLib.sol"; import { Owners } from "./Owners.sol"; contract TSAggregatorTokenTransferProxy is Owners { using SafeTransferLib for address; constructor() { _setOwner(msg.sender, true); } function transferTokens(address token, address from, address to, uint256 amount) external isOwner { require(from == tx.origin || _isContract(from), "Invalid from address"); token.safeTransferFrom(from, to, amount); } function _isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.10; interface IThorchainRouter { function depositWithExpiry( address payable vault, address asset, uint amount, string memory memo, uint expiration ) external payable; }
{ "remappings": [ "hardhat/=node_modules/hardhat/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_ttp","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"feeRecipient","type":"address"}],"name":"FeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"OwnerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"string","name":"memo","type":"string"}],"name":"SwapIn","type":"event"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"owners","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"},{"internalType":"address","name":"_feeRecipient","type":"address"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bool","name":"active","type":"bool"}],"name":"setOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"router","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"string","name":"memo","type":"string"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"swapRouter","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenTransferProxy","outputs":[{"internalType":"contract TSAggregatorTokenTransferProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040526001805534801561001457600080fd5b50604051610c0f380380610c0f833981016040819052610033916100c2565b8061003f336001610065565b600480546001600160a01b0319166001600160a01b0392909216919091179055506100f2565b6001600160a01b03821660008181526020818152604091829020805460ff191685151590811790915591519182527ff74826f11048fa8ecf33e91132bf280f6582ed97548a84e426b56e98526b9316910160405180910390a25050565b6000602082840312156100d457600080fd5b81516001600160a01b03811681146100eb57600080fd5b9392505050565b610b0e806101016000396000f3fe6080604052600436106100745760003560e01c8063469048401161004e578063469048401461011f578063516c731c1461013f578063b4f2e8b81461015f578063ddca3f431461017f57600080fd5b8063022914a7146100805780630701c374146100c55780630eefdbad146100e757600080fd5b3661007b57005b600080fd5b34801561008c57600080fd5b506100b061009b3660046107df565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b3480156100d157600080fd5b506100e56100e036600461084a565b6101a3565b005b3480156100f357600080fd5b50600454610107906001600160a01b031681565b6040516001600160a01b0390911681526020016100bc565b34801561012b57600080fd5b50600354610107906001600160a01b031681565b34801561014b57600080fd5b506100e561015a366004610916565b610463565b34801561016b57600080fd5b506100e561017a366004610952565b6104bf565b34801561018b57600080fd5b5061019560025481565b6040519081526020016100bc565b6001546001146101e75760405162461bcd60e51b815260206004820152600a6024820152695245454e5452414e435960b01b60448201526064015b60405180910390fd5b60026001556004546001600160a01b038581169116141561023b5760405162461bcd60e51b815260206004820152600e60248201526d06e6f2063616c6c696e67207474760941b60448201526064016101de565b600480546040516368155ec160e01b81526001600160a01b0389811693820193909352336024820152306044820152606481018890529116906368155ec190608401600060405180830381600087803b15801561029757600080fd5b505af11580156102ab573d6000803e3d6000fd5b506102c5925050506001600160a01b0387168560006105c0565b6102d96001600160a01b03871685876105c0565b6000846001600160a01b031684846040516102f592919061097e565b6000604051808303816000865af19150503d8060008114610332576040519150601f19603f3d011682016040523d82523d6000602084013e610337565b606091505b50509050806103795760405162461bcd60e51b815260206004820152600e60248201526d06661696c656420746f20737761760941b60448201526064016101de565b504760006103868261063e565b90508b6001600160a01b03166344bc937b828d6000858f8f8a6040518863ffffffff1660e01b81526004016103c0969594939291906109b7565b6000604051808303818588803b1580156103d957600080fd5b505af11580156103ed573d6000803e3d6000fd5b5050505050507fd0905d621f104066424412dcaf4dd7189ca00660fc08a026e5927026b8afa82c3388886104208561067c565b61042a9086610a14565b6104338661067c565b8f8f8f60405161044a989796959493929190610a2c565b60405180910390a1505060018055505050505050505050565b3360009081526020819052604090205460ff166104b15760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016101de565b6104bb82826106c9565b5050565b3360009081526020819052604090205460ff1661050d5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016101de565b6103e882111561055f5760405162461bcd60e51b815260206004820152601c60248201527f6665652063616e206e6f74206265206d6f7265207468616e203130250000000060448201526064016101de565b6002829055600380546001600160a01b0319166001600160a01b0383169081179091556040805184815260208101929092527fc8242dc5446855370b781abbfc5d882af1d1a3cc29143216aba3558feb0ce925910160405180910390a15050565b600060405163095ea7b360e01b81526001600160a01b03841660048201528260248201526000806044836000895af19150506105fb81610726565b6106385760405162461bcd60e51b815260206004820152600e60248201526d1054141493d59157d1905253115160921b60448201526064016101de565b50505050565b60008061064a8361067c565b9050801561067557600354610668906001600160a01b03168261076d565b6106728184610a80565b92505b5090919050565b600060025460001415801561069b57506003546001600160a01b031615155b156106c157612710600254836106b19190610a97565b6106bb9190610ab6565b92915050565b506000919050565b6001600160a01b03821660008181526020818152604091829020805460ff191685151590811790915591519182527ff74826f11048fa8ecf33e91132bf280f6582ed97548a84e426b56e98526b9316910160405180910390a25050565b60003d8261073857806000803e806000fd5b80602081146107505780156107615760009250610766565b816000803e60005115159250610766565b600192505b5050919050565b600080600080600085875af19050806107be5760405162461bcd60e51b815260206004820152601360248201527211551217d514905394d1915497d19052531151606a1b60448201526064016101de565b505050565b80356001600160a01b03811681146107da57600080fd5b919050565b6000602082840312156107f157600080fd5b6107fa826107c3565b9392505050565b60008083601f84011261081357600080fd5b50813567ffffffffffffffff81111561082b57600080fd5b60208301915083602082850101111561084357600080fd5b9250929050565b6000806000806000806000806000806101008b8d03121561086a57600080fd5b6108738b6107c3565b995061088160208c016107c3565b985060408b013567ffffffffffffffff8082111561089e57600080fd5b6108aa8e838f01610801565b909a5098508891506108be60608e016107c3565b975060808d013596506108d360a08e016107c3565b955060c08d01359150808211156108e957600080fd5b506108f68d828e01610801565b9150809450508092505060e08b013590509295989b9194979a5092959850565b6000806040838503121561092957600080fd5b610932836107c3565b91506020830135801515811461094757600080fd5b809150509250929050565b6000806040838503121561096557600080fd5b82359150610975602084016107c3565b90509250929050565b8183823760009101908152919050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b6001600160a01b038781168252861660208201526040810185905260a0606082018190526000906109eb908301858761098e565b9050826080830152979650505050505050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610a2757610a276109fe565b500190565b600060018060a01b03808b168352808a16602084015288604084015287606084015286608084015280861660a08401525060e060c0830152610a7260e08301848661098e565b9a9950505050505050505050565b600082821015610a9257610a926109fe565b500390565b6000816000190483118215151615610ab157610ab16109fe565b500290565b600082610ad357634e487b7160e01b600052601260045260246000fd5b50049056fea26469706673582212208cc5694245836d88347708ae4c7e8d7cb6d0329bf10ebe8b3b2c5060c849e8dc64736f6c634300080a003300000000000000000000000069ba883af416ff5501d54d5e27a1f497fbd97156
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000069ba883af416ff5501d54d5e27a1f497fbd97156
-----Decoded View---------------
Arg [0] : _ttp (address): 0x69ba883af416ff5501d54d5e27a1f497fbd97156
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000069ba883af416ff5501d54d5e27a1f497fbd97156
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.