文件 3 的 3:wildcreditarb_reserve.sol
pragma solidity =0.6.6;
pragma experimental ABIEncoderV2;
import './interfaces/v3pool.sol';
import './lib/SafeMath.sol';
interface IWETH {
function withdraw(uint) external;
}
interface IERC20 {
function balanceOf(address owner) external view returns (uint);
function transfer(address recipient, uint256 amount) external returns (bool);
function approve(address spender, uint value) external returns (bool);
}
interface lendingpair{
function pendingSupplyInterest(address _token, address _account) external view returns(uint);
function accrueAccount(address _account) external;
}
interface feereceipt{
function convert(
address _pair,
bytes calldata _path,
uint _minWildOutput
) external;
}
interface feeconverter{
function wildInput(address _fromToken, uint _fromAmount) external view returns(uint);
}
interface v2pool{
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
contract wildarbr {
using SafeMath for uint;
address payable public owner;
constructor() public {
owner = msg.sender;
IERC20(address(0x08A75dbC7167714CeaC1a8e43a8d643A4EDd625a)).approve(address(0x31FD80bf06453ACE58bea89727e88003f0e691Bb),
0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
}
modifier onlyowner{
require(msg.sender == owner);
_;
}
receive() external payable {}
function deposit() payable external{
}
function _safeTransfer(address token, address to, uint value) private {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(bytes4(keccak256(bytes('transfer(address,uint256)'))), to, value));
}
function withdrawtoken(address tokenaddr, uint amount) external onlyowner{
_safeTransfer(tokenaddr, owner, amount);
}
function withdrawtokenall(address tokenaddr) external onlyowner{
_safeTransfer(tokenaddr, owner, IERC20(tokenaddr).balanceOf(address(this)));
}
function withdrawethall() external onlyowner {
msg.sender.transfer(address(this).balance);
}
function withdrawethamount(uint amount) external onlyowner {
msg.sender.transfer(amount);
}
function uniswapV2Call(address _sender, uint _amount0, uint _amount1, bytes calldata _data) external {
(address pair, address token, uint256 paybackamount, uint256[] memory sellinfo) = abi.decode(_data, (address, address,uint256, uint256[]));
feereceipt(0x487502F921BA3DADAcF63dBF7a57a978C241B72C).convert(pair, abi.encodePacked(token), 0);
if(sellinfo.length > 0){
uint256 receive_amount = IERC20(token).balanceOf(address(this));
IERC20(token).transfer(address(sellinfo[0]
& 0x00ffffffffffffffffffffffffffffffffffffffff), receive_amount);
bool flag;
for(uint i=0; i < sellinfo.length; i++){
pair = address(sellinfo[i] & 0x00ffffffffffffffffffffffffffffffffffffffff);
if((i + 1) == sellinfo.length){
token = address(this);
}else{
token = address(sellinfo[i+1] & 0x00ffffffffffffffffffffffffffffffffffffffff);
}
flag = (sellinfo[i] >> 160 & 0x00ff) == 1;
receive_amount = v2out(pair, flag, receive_amount);
if(flag){
v2pool(pair).swap(0, receive_amount, token, new bytes(0));
}else{
v2pool(pair).swap(receive_amount, 0, token, new bytes(0));
}
}
}
IERC20(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).transfer(msg.sender, paybackamount);
}
function wild_credit_accrue_arb(uint256 ethshare, address lptoken, address pair, address path,address[] memory accounts, uint256[] memory sellinfo) public payable{
if(block.number > msg.value){
return;
}
uint256 gasstart = gasleft();
uint256 wildin;
uint256 inputamount;
uint256 weth_payback;
for(uint256 i = 0; i < accounts.length; i++){
lendingpair(pair).accrueAccount(accounts[i]);
}
uint256 lpamount = IERC20(lptoken).balanceOf(address(0x487502F921BA3DADAcF63dBF7a57a978C241B72C));
if(path == address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)){
inputamount = lpamount - lpamount * ethshare / 100e18;
}else{
inputamount = lpamount;
}
wildin = feeconverter(address(0x31FD80bf06453ACE58bea89727e88003f0e691Bb)).wildInput(path, inputamount);
bytes memory returnData;
(, returnData) = address(0xc36068bf159414beb497f8ECe08763868149B2Fe).staticcall(abi.encodeWithSelector(0x0902f1ac));
(uint reserve0,uint reserve1, ) = abi.decode(returnData, (uint,uint,uint));
weth_payback = getAmountIn(wildin, reserve1, reserve0);
bytes memory data = abi.encode(pair, path, weth_payback, sellinfo);
v2pool(0xc36068bf159414beb497f8ECe08763868149B2Fe).swap(wildin, 0, address(this), data);
wildin = IERC20(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).balanceOf(address(this)) - 1;
require(wildin > (tx.gasprice * (gasstart - gasleft())), "fuck");
IWETH(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)).withdraw(wildin);
msg.sender.transfer(wildin);
}
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'LIQUIDITY');
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint numerator = reserveIn.mul(amountOut).mul(1000);
uint denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}
function v2out(address pool, bool first, uint256 amountIn) private view returns (uint256 amountOut){
bytes memory returnData;
(, returnData) = pool.staticcall(abi.encodeWithSelector(0x0902f1ac));
(uint reserve0,uint reserve1, ) = abi.decode(returnData, (uint,uint,uint));
(uint reserveInput, uint reserveOutput) = (first) ? (reserve0, reserve1) : (reserve1, reserve0);
amountOut = getAmountOut(amountIn, reserveInput, reserveOutput);
return(amountOut);
}
}