Created
March 4, 2020 18:31
-
-
Save muellerberndt/9a06067124a57bc78679401bf69f40d6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity ^0.5.0; | |
import "./SafeMath.sol"; | |
// A liquidity pool that also does collateralized loans!! | |
contract zBx { | |
using SafeMath for uint256; | |
mapping (address => uint256) public token_balances; | |
mapping (address => uint256) public ether_balances; | |
struct ConstantProductPool { | |
uint256 eth_reserve; | |
uint256 token_reserve; | |
} | |
ConstantProductPool public exchange; | |
constructor() public payable { | |
exchange = ConstantProductPool(msg.value, 1000000000000000000); | |
} | |
function getInputPrice(uint256 input_amount, uint256 input_reserve, uint256 output_reserve) internal pure returns (uint256) { | |
require(input_reserve > 0 && output_reserve > 0); | |
uint256 input_amount_with_fee = input_amount.mul(997); | |
uint256 numerator = input_amount_with_fee.mul(output_reserve); | |
uint256 denominator = (input_reserve.mul(1000)).add(input_amount_with_fee); | |
return numerator / denominator; | |
} | |
function getOutputPrice(uint256 output_amount, uint256 input_reserve, uint256 output_reserve) internal pure returns (uint256) { | |
require(input_reserve > 0 && output_reserve > 0); | |
uint256 numerator = input_reserve.mul(output_amount).mul(1000); | |
uint256 denominator = (output_reserve.sub(output_amount)).mul(997); | |
return numerator.div(denominator); | |
} | |
function tokenToEth(uint256 eth_bought) public returns (uint256) { | |
require(eth_bought > 0); | |
uint256 tokens_sold = getOutputPrice(eth_bought, exchange.token_reserve, exchange.eth_reserve); | |
// tokens sold is always > 0 | |
token_balances[msg.sender] = token_balances[msg.sender].sub(tokens_sold); | |
msg.sender.transfer(eth_bought); | |
exchange.token_reserve = exchange.token_reserve.add(tokens_sold); | |
exchange.eth_reserve = exchange.eth_reserve.sub(eth_bought); | |
return tokens_sold; | |
} | |
function ethToToken() public payable returns (uint256) { | |
uint256 eth_sold = msg.value; | |
require(eth_sold > 0); | |
uint256 tokens_bought = getInputPrice(eth_sold, exchange.eth_reserve.sub(eth_sold), exchange.token_reserve); | |
token_balances[msg.sender] = token_balances[msg.sender].add(tokens_bought); | |
exchange.token_reserve = exchange.token_reserve.sub(tokens_bought); | |
exchange.eth_reserve = exchange.eth_reserve.add(msg.value); | |
return tokens_bought; | |
} | |
function() external payable { | |
ethToToken(); | |
} | |
function getTokenToEthOutputPrice(uint256 eth_bought) public view returns (uint256) { | |
return getOutputPrice(eth_bought, exchange.token_reserve, exchange.eth_reserve); | |
} | |
function getEthToTokenInputPrice(uint256 eth_sold) public view returns (uint256) { | |
return getInputPrice(eth_sold, exchange.eth_reserve.sub(eth_sold), exchange.token_reserve); | |
} | |
function minCollateral(uint256 eth_borrow) internal view returns (uint256) { | |
// Minimum collateralization is 200%! | |
return getTokenToEthOutputPrice(eth_borrow).mul(2); | |
} | |
function hasEnoughCollateral(uint256 eth_borrow, address borrower) internal view returns (bool) { | |
return (token_balances[borrower] >= minCollateral(eth_borrow)); | |
} | |
function takeLoanCollateralizedByToken(uint256 eth_borrow) public { | |
require(hasEnoughCollateral(eth_borrow, msg.sender)); | |
msg.sender.transfer(eth_borrow); | |
} | |
} | |
contract FlashLoan { | |
constructor() payable public { | |
} | |
function getLoan(uint256 amount) public payable { | |
msg.sender.transfer(amount); | |
} | |
function() payable external { | |
} | |
} | |
contract SymbolicArbitrage { | |
event AssertionFailed(string message); | |
uint256 public starting_balance; | |
zBx public defi; | |
FlashLoan public flashloan; | |
constructor(address payable _loan, address payable _zBx) public payable { | |
starting_balance = address(this).balance; | |
defi = zBx(_zBx); | |
flashloan = FlashLoan(_loan); | |
} | |
function checkProfit() public view { | |
assert(address(this).balance <= starting_balance); | |
} | |
function getLoan(uint256 amount) public { | |
flashloan.getLoan(amount); | |
} | |
function tokenToEth(uint256 eth_bought) public { | |
defi.tokenToEth(eth_bought); | |
} | |
function ethToToken(uint256 eth_sold) public returns (uint256) { | |
address(defi).call.value(eth_sold)(""); | |
} | |
function takeLoanCollateralizedByToken(uint256 eth_borrow) public { | |
defi.takeLoanCollateralizedByToken(eth_borrow); | |
} | |
function () payable external { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment