Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added contracts/core/MasterChef.sol
Empty file.
52 changes: 51 additions & 1 deletion contracts/core/MiniYak.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,59 @@
pragma solidity ^0.8.0;

import "../libs/openzeppelin/token/ERC20/ERC20.sol";
import "../libs/openzeppelin/token/ERC20/IPair.sol";
import "../libs/openzeppelin/access/Ownable.sol";
import "../libs/openzeppelin/utils/math/SafeMath.sol";

contract MiniYak is ERC20 {
contract MiniYak is ERC20, Ownable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to limit the transfer function to only transfer values higher than mini, users with less mYak than the defined mini would cause problems

using SafeMath for uint;
IPair private swapPair;
bool private swapsEnabled;
event Deposit(address indexed dst, uint amount);

constructor() ERC20("MiniYak", "MYAK") {}
uint constant internal mini = 1000000;

/**
* @dev Throws if called by any account other than the owner.
*/
modifier swapsAllowed() {
require( swapsEnabled == true, "Ownable: caller is not the owner");
require(address(swapPair) != address(0));
_;
}

receive() external payable {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MiniYak does not need to deal with payable, it'll receive YakToken which is ERC20 and wrap it

// only accept AVAX via fallback from the owner when rewards are distributed by masterChef
assert(msg.sender == owner());
}

function wrap() public payable {
_mint(msg.sender, (msg.value).mul(mini));
emit Deposit(msg.sender, msg.value);
}

function withdrawOwnerOnly(uint amount) public onlyOwner {
payable(msg.sender).transfer(amount);
}

function unwrap(uint amount) public {
_burn(msg.sender,amount.div(mini));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should require here that the amount is bigger than mini, otherwise the division will yield the result of 0.

payable(msg.sender).transfer(amount.div(mini));
}

function assignSwapPair(address pair) public onlyOwner {
require(address(pair)!= address(0),"Cannot assign to a dead address");
require(IPair(pair).token0() == address(this) || IPair(pair).token1() == address(this));
swapPair = IPair(pair);
}

function swapFromAVAX(uint amount) public swapsAllowed {
swapPair.swap(0, amount, msg.sender, new bytes(0));
}

function swapToAVAX(uint amount) public swapsAllowed {
swapPair.swap(amount, 0, msg.sender, new bytes(0));
}

}
51 changes: 49 additions & 2 deletions contracts/core/YakAVAX.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,56 @@
pragma solidity ^0.8.0;

import "../libs/openzeppelin/token/ERC20/ERC20.sol";
import "../libs/openzeppelin/token/ERC20/IPair.sol";
import "../libs/openzeppelin/access/Ownable.sol";

contract YakAVAX is ERC20 {
contract YakAVAX is ERC20, Ownable {
IPair private swapPair;
bool private swapsEnabled;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need an admin function to disabled it and re-enable

event Deposit(address indexed dst, uint amount);
constructor() ERC20("YakAVAX", "YAKX") {

constructor() ERC20("YakAVAX", "YAKX") {}
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier swapsAllowed() {
require( swapsEnabled == true, "Ownable: caller is not the owner");
require(address(swapPair) != address(0));
_;
}

receive() external payable {
// only accept AVAX via fallback from the owner when rewards are distributed by masterChef
assert(msg.sender == owner());
}

function wrap() public payable {
_mint(msg.sender, msg.value);
emit Deposit(msg.sender, msg.value);
}

function withdrawOwnerOnly(uint amount) public onlyOwner {
payable(msg.sender).transfer(amount);
}

function unwrap(uint amount) public {
_burn(msg.sender,amount);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's a good idea to require that the contract has the underlying AVAX available

payable(msg.sender).transfer(amount);
}

function assignSwapPair(address pair) public onlyOwner {
require(address(pair)!= address(0),"Cannot assign to a dead address");
require(IPair(pair).token0() == address(this) || IPair(pair).token1() == address(this));
swapPair = IPair(pair);
}

function swapForYakAVAX(uint amount) public swapsAllowed {
swapPair.swap(0, amount, msg.sender, new bytes(0));
}

function swapForAVAX(uint amount) public swapsAllowed {
swapPair.swap(amount, 0, msg.sender, new bytes(0));
}

}
13 changes: 13 additions & 0 deletions contracts/libs/openzeppelin/token/ERC20/IPair.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC20.sol";

interface IPair is IERC20 {
function token0() external pure returns (address);
function token1() external pure returns (address);
function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
function mint(address to) external returns (uint liquidity);
function sync() external;
}
13 changes: 13 additions & 0 deletions contracts/libs/openzeppelin/token/ERC20/IYAK.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IERC20.sol";

interface IYAK is IERC20 {
function wrap() external payable;
function withdrawOwnerOnly(uint amount) external;
function unwrap() external;
function assignSwapPair(address pair) external;
function mint(address to) external returns (uint liquidity);
function sync() external;
}
38 changes: 38 additions & 0 deletions test/YakAVAX.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect } from "chai"
import { ethers } from "hardhat"
import {run} from "hardhat"
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { Contract } from "@ethersproject/contracts"

describe("YakAVAX", async function() {

let owner: SignerWithAddress
let account: SignerWithAddress
let yakAVAXContract: Contract

before(async function() {
//this makes sure the newest changes are compiled and pushed to the fork node
run("compile")
})

beforeEach(async function() {
owner = (await ethers.getSigners())[0]
account = (await ethers.getSigners())[1]
})

it("Can be deployed", async function() {
const factory = await ethers.getContractFactory("YakAVAX")
yakAVAXContract = await factory.connect(owner).deploy()
// await expect(miniYakContract.deployed()).to.be.reverted
await yakAVAXContract.deployed()
console.log("Account balance of Owner before deposit:", (await owner.getBalance()).toString());
await yakAVAXContract.connect(owner).deposit({from: owner.address, value: "40000000000000000000"});
console.log("Account balance after deposit:", (await owner.getBalance()).toString());
console.log("YakAVAX balance of Owner after deposit:", (await yakAVAXContract.connect(owner).balanceOf(await owner.getAddress())).toString());
await yakAVAXContract.connect(owner).withdraw("40000000000000000000");
console.log("Account balance of owner after withdraw:", (await owner.getBalance()).toString());
console.log("Account balance:", (await yakAVAXContract.connect(owner).balanceOf(await owner.getAddress())).toString());

})

})