Skip to content

Commit

Permalink
add rewardDistributor-test.js
Browse files Browse the repository at this point in the history
  • Loading branch information
Fatel committed Jan 27, 2024
1 parent bc8dd01 commit 7f27fe1
Show file tree
Hide file tree
Showing 10 changed files with 355 additions and 179 deletions.
16 changes: 8 additions & 8 deletions contracts/OPZap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IStageShare} from "./share/IStageShare.sol";
import {IUniV2ClassPair} from "./common/IUniV2ClassPair.sol";
import {Erc20Utils} from "./common/Erc20Utils.sol";
import {IxOLE} from "./common/IxOLE.sol";
import {ISOLE} from "./common/ISOLE.sol";
import {IWETH} from "./common/IWETH.sol";

contract OPZap is IOPZapV1 {
Expand All @@ -19,15 +19,15 @@ contract OPZap is IOPZapV1 {
IERC20 public immutable OLE; // Address of the OLE token
IWETH public immutable WETH; // Native token of the blockchain (e.g., ETH on Ethereum)
IUniV2ClassPair public immutable OLE_ETH; // Address of the token pair for liquidity : OLE/ETH
address public immutable XOLE; // Address of the OpenLeverage XOLE token
address public immutable SOLE; // Address of the OpenLeverage SOLE token
IStageShare public immutable STAGE; // Address of the OpenLeverage Stage share contract
uint256 public immutable DEX_FEES; // 0.3% dex fees (e.g., 20 means 0.2%)
constructor(IERC20 _ole, IWETH _weth, IUniV2ClassPair _pair, uint256 _dexFee, address _xole, IStageShare _stageShare) {
constructor(IERC20 _ole, IWETH _weth, IUniV2ClassPair _pair, uint256 _dexFee, address _sole, IStageShare _stageShare) {
OLE = _ole;
WETH = _weth;
OLE_ETH = _pair;
DEX_FEES = _dexFee;
XOLE = _xole;
SOLE = _sole;
STAGE = _stageShare;
}

Expand All @@ -42,16 +42,16 @@ contract OPZap is IOPZapV1 {
WETH.deposit{value: msg.value}();
uint256 lpReturn = _addLpByETH(msg.value);
if (lpReturn < minLpReturn) revert InsufficientLpReturn();
OLE_ETH.safeApprove(XOLE, lpReturn);
IxOLE(XOLE).create_lock_for(msg.sender, lpReturn, unlockTime);
OLE_ETH.safeApprove(SOLE, lpReturn);
ISOLE(SOLE).create_lock_for(msg.sender, lpReturn, unlockTime);
}

function increaseXoleByETH(uint256 minLpReturn) external payable override {
WETH.deposit{value: msg.value}();
uint256 lpReturn = _addLpByETH(msg.value);
if (lpReturn < minLpReturn) revert InsufficientLpReturn();
OLE_ETH.safeApprove(XOLE, lpReturn);
IxOLE(XOLE).increase_amount_for(msg.sender, lpReturn);
OLE_ETH.safeApprove(SOLE, lpReturn);
ISOLE(SOLE).increase_amount_for(msg.sender, lpReturn);
}

function buySharesByETH(uint256 stageId, uint256 shares, uint256 timestamp, bytes memory signature) external payable override {
Expand Down
2 changes: 1 addition & 1 deletion contracts/common/IxOLE.sol → contracts/common/ISOLE.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

interface IxOLE {
interface ISOLE {
function create_lock_for(address to, uint256 _value, uint256 _unlock_time) external;

function increase_amount_for(address to, uint256 _value) external;
Expand Down
24 changes: 12 additions & 12 deletions contracts/linkup/LinkUp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
pragma solidity ^0.8.21;

import "@openzeppelin/contracts/access/Ownable.sol";
import "../common/IxOLE.sol";
import "../common/ISOLE.sol";
import "../IOPZapV1.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Erc20Utils} from "../common/Erc20Utils.sol";

contract LinkUp is Ownable {
using Erc20Utils for IERC20;

IxOLE public immutable xOLEToken; // xOLE Token, immutable
ISOLE public immutable sOLEToken; // sOLE Token, immutable
IERC20 public immutable OLE; // Address of the OLE token
IOPZapV1 public immutable ZAP;
uint256 public constant MIN_XOLE_BALANCE = 100 * 10 ** 18; // Example: 100 xOLE (adjust as needed)
uint256 public constant MIN_SOLE_BALANCE = 100 * 10 ** 18; // Example: 100 sOLE (adjust as needed)
address public signerAddress;
uint256 public joinFee = 0.0015 ether;
mapping(address => address) public inviterOf;
Expand All @@ -35,9 +35,9 @@ contract LinkUp is Ownable {
error InvalidNewSignerAddress();
error InvalidSignatureLength();

constructor(address signer, address _xOLETokenAddress, IERC20 _ole, IOPZapV1 _zap) Ownable(msg.sender) {
constructor(address signer, address _sOLETokenAddress, IERC20 _ole, IOPZapV1 _zap) Ownable(msg.sender) {
signerAddress = signer;
xOLEToken = IxOLE(_xOLETokenAddress); // Set the xOLE Token address here
sOLEToken = ISOLE(_sOLETokenAddress); // Set the sOLE Token address here
OLE = _ole;
ZAP = _zap;
}
Expand All @@ -55,24 +55,24 @@ contract LinkUp is Ownable {
uint256 secondTierInviterFeePercent = 0;
uint256 protocolFeePercent = 100;

// Check xOLE balances of inviters
bool directInviterOwnsXOLE = xOLEToken.balanceOf(inviter) >= MIN_XOLE_BALANCE;
bool secondTierInviterOwnsXOLE = false;
// Check sOLE balances of inviters
bool directInviterOwnsSOLE = sOLEToken.balanceOf(inviter) >= MIN_SOLE_BALANCE;
bool secondTierInviterOwnsSOLE = false;
address secondTierInviter = inviterOf[inviter];
if (secondTierInviter != address(0)) {
secondTierInviterOwnsXOLE = xOLEToken.balanceOf(secondTierInviter) >= MIN_XOLE_BALANCE;
secondTierInviterOwnsSOLE = sOLEToken.balanceOf(secondTierInviter) >= MIN_SOLE_BALANCE;
}

// Calculate fee distribution percent
if (directInviterOwnsXOLE && secondTierInviterOwnsXOLE) {
if (directInviterOwnsSOLE && secondTierInviterOwnsSOLE) {
directInviterFeePercent = 75;
secondTierInviterFeePercent = 25;
protocolFeePercent = 0;
} else if (directInviterOwnsXOLE) {
} else if (directInviterOwnsSOLE) {
directInviterFeePercent = 80;
secondTierInviterFeePercent = 15;
protocolFeePercent = 5;
} else if (secondTierInviterOwnsXOLE) {
} else if (secondTierInviterOwnsSOLE) {
directInviterFeePercent = 65;
secondTierInviterFeePercent = 30;
protocolFeePercent = 5;
Expand Down
4 changes: 2 additions & 2 deletions contracts/mocks/MockXOLE.sol → contracts/mocks/MockSOLE.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.21;

import {IxOLE} from "../common/IxOLE.sol";
import {ISOLE} from "../common/ISOLE.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Erc20Utils} from "../common/Erc20Utils.sol";

contract MockXOLE is IxOLE {
contract MockSOLE is ISOLE {
using Erc20Utils for IERC20;

uint256 constant WEEK = 7 * 86400; // all future times are rounded by week
Expand Down
2 changes: 0 additions & 2 deletions contracts/share/ShareHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pragma solidity 0.8.21;
import {IStageShare} from "./IStageShare.sol";

contract ShareHelper {

constructor() {}

function getRewards(IStageShare stageShare, address holder, uint256[] memory stageIds) external view returns (uint256[] memory rewards) {
Expand All @@ -16,5 +15,4 @@ contract ShareHelper {
rewards[i] = stageShare.getRewards(queryIds, holder);
}
}

}
34 changes: 17 additions & 17 deletions test/linkUp-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ describe("LinkUp Contract", function() {
let LinkUp;
let linkUp;
let MockXOLE;
let mockxOLE;
let mocksOLE;
let owner;
let addr1;
let addr2;
Expand All @@ -23,20 +23,20 @@ describe("LinkUp Contract", function() {
let zapCtr = await (await ethers.getContractFactory("MockZap")).deploy(oleCtr, wethCtr);
await oleCtr.mint(await zapCtr.getAddress(), ethers.parseEther("10000"));
LinkUp = await ethers.getContractFactory("LinkUp");
MockXOLE = await ethers.getContractFactory("MockXOLE");
mockxOLE = await MockXOLE.deploy(ZERO_ADDRESS);
MockXOLE = await ethers.getContractFactory("MockSOLE");
mocksOLE = await MockXOLE.deploy(ZERO_ADDRESS);
[owner, addr1, addr2, ...addrs] = await ethers.getSigners();
signer = addrs[9];
linkUp = await LinkUp.connect(owner).deploy(signer, mockxOLE, oleCtr, zapCtr);
linkUp = await LinkUp.connect(owner).deploy(signer, mocksOLE, oleCtr, zapCtr);
});

async function setupXOLEBalances(directInviterHasXOLE, secondTierInviterHasXOLE) {
if (directInviterHasXOLE) {
await mockxOLE.mint(addr1.address, ethers.parseEther("100")); // Direct inviter has xOLE
await mocksOLE.mint(addr1.address, ethers.parseEther("100")); // Direct inviter has sOLE
} // else do not mint to simulate no balance

if (secondTierInviterHasXOLE) {
await mockxOLE.mint(addr2.address, ethers.parseEther("100")); // Second-tier inviter has xOLE
await mocksOLE.mint(addr2.address, ethers.parseEther("100")); // Second-tier inviter has sOLE
} // else do not mint to simulate no balance
}

Expand Down Expand Up @@ -101,16 +101,16 @@ describe("LinkUp Contract", function() {
.to.be.revertedWithCustomError(linkUp, "AlreadyJoined");
});

it("Should distribute fees correctly when only the direct inviter owns xOLE", async function() {
// addr1 is the direct inviter and owns enough xOLE tokens
// addr2 is the second-tier inviter and does not own enough xOLE tokens
it("Should distribute fees correctly when only the direct inviter owns sOLE", async function() {
// addr1 is the direct inviter and owns enough sOLE tokens
// addr2 is the second-tier inviter and does not own enough sOLE tokens

// Sign inviter address
const inviter = addr1.address; // Direct inviter
const secondTierInviter = addr2.address; // Second-tier inviter
const invitee = addrs[3].address; // New user being invited

// Ensure addr2 has no xOLE to affect the distribution
// Ensure addr2 has no sOLE to affect the distribution
await setupXOLEBalances(true, false);

// Generate signatures
Expand Down Expand Up @@ -139,9 +139,9 @@ describe("LinkUp Contract", function() {
);
});

it("Should distribute fees correctly when only the second-tier inviter owns xOLE", async function() {
// Setup: addr2 is the direct inviter and does not own enough xOLE tokens
// addr1 is the second-tier inviter and owns enough xOLE tokens
it("Should distribute fees correctly when only the second-tier inviter owns sOLE", async function() {
// Setup: addr2 is the direct inviter and does not own enough sOLE tokens
// addr1 is the second-tier inviter and owns enough sOLE tokens
// Sign inviter address
const inviter = addr1.address; // Direct inviter
const secondTierInviter = addr2.address; // Second-tier inviter
Expand Down Expand Up @@ -175,8 +175,8 @@ describe("LinkUp Contract", function() {
);
});

it("Should distribute fees correctly when both inviters own xOLE", async function() {
// Setup: Both addr1 and addr2 own enough xOLE tokens
it("Should distribute fees correctly when both inviters own sOLE", async function() {
// Setup: Both addr1 and addr2 own enough sOLE tokens
const inviter = addr1.address; // Direct inviter
const secondTierInviter = addr2.address; // Second-tier inviter
const invitee = addrs[3].address; // New user being invited
Expand Down Expand Up @@ -209,8 +209,8 @@ describe("LinkUp Contract", function() {
);
});

it("Should distribute fees correctly when neither inviter owns xOLE", async function() {
// Setup: Neither addr1 nor addr2 owns enough xOLE tokens
it("Should distribute fees correctly when neither inviter owns sOLE", async function() {
// Setup: Neither addr1 nor addr2 owns enough sOLE tokens
const inviter = addr1.address; // Direct inviter
const secondTierInviter = addr2.address; // Second-tier inviter
const invitee = addrs[3].address; // New user being invited
Expand Down
Loading

0 comments on commit 7f27fe1

Please sign in to comment.