编译器
0.8.17+commit.8df45f5f
文件 1 的 6:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 6:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from, address to, uint256 amount) external returns (bool);
}
文件 3 的 6:IUniswapV2Router01.sol
pragma solidity >=0.6.2;
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
文件 4 的 6:IUniswapV2Router02.sol
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
文件 5 的 6:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 6 的 6:RampableDexService.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
contract RampableDexService is Ownable {
IUniswapV2Router02 public uniswapRouterV2;
address payable public payoutAddress;
mapping (address => bool) public whitelistToToken;
constructor(address _uniswapRouterV2, address _payoutAddress, address[] memory _whitelistToToken) {
require(_uniswapRouterV2 != address(0), "Uniswap Router V2 address cannot be address 0");
require(_payoutAddress != address(0), "Payout address cannot be address 0");
uniswapRouterV2 = IUniswapV2Router02(_uniswapRouterV2);
payoutAddress = payable(_payoutAddress);
for (uint256 i; i <= _whitelistToToken.length - 1; i++)
{
whitelistToToken[_whitelistToToken[i]] = true;
}
}
receive() external payable {
assert(msg.sender == address(uniswapRouterV2));
}
function changeRouterAddress(address _uniswapRouterV2) external onlyOwner {
require(_uniswapRouterV2 != address(0), "Uniswap Router V2 address cannot be address 0");
uniswapRouterV2 = IUniswapV2Router02(_uniswapRouterV2);
}
function changePayoutAddress(address _payoutAddress) external onlyOwner {
require(_payoutAddress != address(0), "Payout address cannot be address 0");
payoutAddress = payable(_payoutAddress);
}
function changeWhitelistToToken(address[] memory _whitelistToToken, bool[] memory _isWhitelist) external onlyOwner {
require(_whitelistToToken.length == _isWhitelist.length, "Token address length is not matched with approval length");
for (uint256 i; i < _whitelistToToken.length - 1; i++)
{
require(_whitelistToToken[i] != address(0), "Token address cannot be address 0");
whitelistToToken[_whitelistToToken[i]] = _isWhitelist[i];
}
}
function offRamp(
address _fromToken,
address _toToken,
uint256 _amount,
uint256 _slippagePercentage
) public {
require(_amount > 0, "Amount must be greater than 0");
require(whitelistToToken[_toToken], "Destination token is not whitelisted");
IERC20(_fromToken).transferFrom(msg.sender, address(this), _amount);
uint256 allowance = IERC20(_fromToken).allowance(address(this), address(uniswapRouterV2));
if (allowance < _amount) IERC20(_fromToken).approve(address(uniswapRouterV2), type(uint256).max);
address[] memory path = new address[](2);
path[0] = _fromToken;
path[1] = _toToken;
uint[] memory predicted = uniswapRouterV2.getAmountsOut(_amount, path);
uint256 _amountOutMin = predicted[1] * _slippagePercentage / 1000;
bool isNative = _toToken == uniswapRouterV2.WETH();
if (isNative) {
uint256 balanceBefore = address(this).balance;
uniswapRouterV2.swapExactTokensForETHSupportingFeeOnTransferTokens(
_amount,
_amountOutMin,
path,
address(this),
block.timestamp + 300
);
payoutAddress.transfer(address(this).balance - balanceBefore);
} else {
uint256 balanceBefore = IERC20(_toToken).balanceOf(address(this));
uniswapRouterV2
.swapExactTokensForTokensSupportingFeeOnTransferTokens(
_amount,
_amountOutMin,
path,
address(this),
block.timestamp + 300
);
uint256 balance = IERC20(_toToken).balanceOf(address(this)) - balanceBefore;
IERC20(_toToken).transfer(payoutAddress, balance);
}
}
}
{
"compilationTarget": {
"contracts/RampableDexService.sol": "RampableDexService"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_uniswapRouterV2","type":"address"},{"internalType":"address","name":"_payoutAddress","type":"address"},{"internalType":"address[]","name":"_whitelistToToken","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"_payoutAddress","type":"address"}],"name":"changePayoutAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_uniswapRouterV2","type":"address"}],"name":"changeRouterAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_whitelistToToken","type":"address[]"},{"internalType":"bool[]","name":"_isWhitelist","type":"bool[]"}],"name":"changeWhitelistToToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromToken","type":"address"},{"internalType":"address","name":"_toToken","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_slippagePercentage","type":"uint256"}],"name":"offRamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"payoutAddress","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapRouterV2","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistToToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]