Skip to content

Commit

Permalink
Subscription tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Mill1995 committed Jun 18, 2024
1 parent 796b3ed commit 6ffc483
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 220 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ coverage
broadcast
deployed_contracts.json
_audit
coverage_foundry
lcov.info
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ test-fork :; forge test --summary --detailed --match-path ./test/foundry/fork/*.

snapshot :; forge snapshot

coverage:; forge coverage --report summary

coverageReport:; forge coverage --report lcov
# then run genhtml -o coverage_foundry lcov.info to generate the HTML files

format :; forge fmt

anvil :; anvil -m 'test test test test test test test test test test test junk' --steps-tracing --block-time 1
Expand Down
200 changes: 0 additions & 200 deletions contracts/dao/MultiSigWallet.sol

This file was deleted.

17 changes: 13 additions & 4 deletions contracts/dao/Subscription.sol
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,14 @@ contract Subscription is ReentrancyGuard {
* @param _period Subscription period in months (e.g., 1, 3, 6, 12).
*/
function activeSubscription(address _token, uint256 _period) external payable nonReentrant {
// Check if token is allowed for deposits
if (_token != IOwnablee(OWNABLE).PAYOUT_TOKEN() && _token != address(0)) {
require(IOwnablee(OWNABLE).isDepositAsset(_token), "activeSubscription: not allowed asset");
}

uint256 expectAmount = getExpectedSubscriptionAmount(_token, _period);

// Send ETH or ERC20 token to this address
if (_token == address(0)) {
require(msg.value >= expectAmount, "activeSubscription: Insufficient paid");
if (msg.value > expectAmount) {
Expand All @@ -146,7 +149,8 @@ contract Subscription is ReentrancyGuard {
uint256 usdcAmount;
address usdcToken = IOwnablee(OWNABLE).USDC_TOKEN();
address vabToken = IOwnablee(OWNABLE).PAYOUT_TOKEN();
// if token is VAB, send USDC(convert from VAB to USDC) to wallet

// if token is VAB, convert VAB to USDC and send it to the VAB Wallet
if (_token == vabToken) {
bytes memory swapArgs = abi.encode(expectAmount, _token, usdcToken);
usdcAmount = IUniHelper(UNI_HELPER).swapAsset(swapArgs);
Expand All @@ -160,7 +164,7 @@ contract Subscription is ReentrancyGuard {

bytes memory swapArgs = abi.encode(amount60, _token, vabToken);
uint256 vabAmount = IUniHelper(UNI_HELPER).swapAsset(swapArgs);
// Transfer VAB to wallet
// Transfer VAB to VAB wallet (60%)
Helper.safeTransfer(vabToken, IOwnablee(OWNABLE).VAB_WALLET(), vabAmount);

if (_token == usdcToken) {
Expand All @@ -172,10 +176,11 @@ contract Subscription is ReentrancyGuard {
bytes memory swapArgs1 = abi.encode(expectAmount - amount60, _token, usdcToken);
usdcAmount = IUniHelper(UNI_HELPER).swapAsset(swapArgs1);
}
// Transfer USDC to wallet
// Transfer USDC to wallet (40%)
Helper.safeTransfer(usdcToken, IOwnablee(OWNABLE).VAB_WALLET(), usdcAmount);
}

// Update user subscription info
UserSubscription storage subscription = subscriptionInfo[msg.sender];
if (isActivedSubscription(msg.sender)) {
uint256 oldPeriod = subscription.period;
Expand Down Expand Up @@ -234,7 +239,8 @@ contract Subscription is ReentrancyGuard {
uint256 scriptAmount = _period * IProperty(DAO_PROPERTY).subscriptionAmount();

if (_period < 3) {
scriptAmount = scriptAmount;
//@audit -low not needed ?
// scriptAmount = scriptAmount;
} else if (_period >= 3 && _period < 6) {
scriptAmount = scriptAmount * (100 - discountList[0]) * 1e8 / 1e10;
} else if (_period >= 6 && _period < 12) {
Expand All @@ -244,6 +250,9 @@ contract Subscription is ReentrancyGuard {
}

if (_token == vabToken) {
//@audit-issue Why use PERCENT40 here ?
// This will result in a wrong subscription price if the user pays with VAB
// He always pays only 40% of the actual subscription amount
expectAmount_ = IUniHelper(UNI_HELPER).expectedAmount(scriptAmount * PERCENT40 / 1e10, usdcToken, _token);
} else if (_token == usdcToken) {
expectAmount_ = scriptAmount;
Expand Down
33 changes: 23 additions & 10 deletions contracts/dao/UniHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -197,33 +197,45 @@ contract UniHelper is IUniHelper, ReentrancyGuard {
* @return amount_ The estimated amount of incoming asset.
*/
function expectedAmount(
uint256 _depositAmount,
address _depositAsset,
address _incomingAsset
uint256 _depositAmount, //e: 2.99
address _depositAsset, //e: USDC
address _incomingAsset //e: USDT
)
external
view
override
returns (uint256 amount_)
{
// deposit -> WETH
// _depositAsset -> WETH
uint256 weth_amount;
if (_depositAsset == address(0)) {
weth_amount = _depositAmount;
} else {
// example:
// User wants to activate a subscription paying with USDT
// We want to check how much WETH we need for the given _depositAmount + asset
// we check if there is a pool first
(address router, address[] memory path) = __checkPool(_depositAsset, address(0));
require(router != address(0), "eA: no pool dA/weth");

// now we can calculate the amount of WETH we'll need
// deposit amount (subscription amount) = 2990000
// path: [USDC, WETH]
// WETH amount = 862454909597929 = 0.000862454909597929
weth_amount = IUniswapV2Router(router).getAmountsOut(_depositAmount, path)[1];
}

// WETH -> income
// WETH -> _incomingAsset
if (_incomingAsset == address(0)) {
amount_ = weth_amount;
} else {
// Now we want to check how much USDT we need for the calculated WETH
// we check if there is a pool again
(address router, address[] memory path) = __checkPool(address(0), _incomingAsset);
require(router != address(0), "eA: no pool weth/iA");

// path: [WETH, USDT]
// WETH amount = 862454909597929
// USDT amount = ???
//@audit-issue There is no liquidty for this token pair
amount_ = IUniswapV2Router(router).getAmountsOut(weth_amount, path)[1];
}
}
Expand Down Expand Up @@ -311,7 +323,7 @@ contract UniHelper is IUniHelper, ReentrancyGuard {
require(address(this).balance >= _depositAmount, "sEToT: insufficient");

__approveMaxAsNeeded(_path[0], _router, _depositAmount);

//@audit q: why use block.timestamp + 1 as deadline here ?
amounts_ = IUniswapV2Router(_router).swapExactETHForTokens{ value: address(this).balance }(
_expectedAmount, _path, address(this), block.timestamp + 1
);
Expand All @@ -337,6 +349,7 @@ contract UniHelper is IUniHelper, ReentrancyGuard {
{
__approveMaxAsNeeded(_path[0], _router, _depositAmount);

//@audit q: why use block.timestamp + 1 as deadline here ?
amounts_ = IUniswapV2Router(_router).swapExactTokensForETH(
_depositAmount, _expectedAmount, _path, address(this), block.timestamp + 1
);
Expand Down Expand Up @@ -385,8 +398,8 @@ contract UniHelper is IUniHelper, ReentrancyGuard {
* @return router The address of the router where the pool exists, and path The token path of the pool.
*/
function __checkPool(
address _depositAsset,
address _incomeAsset
address _depositAsset, // e: USDC
address _incomeAsset // ETH
)
private
view
Expand Down
Loading

0 comments on commit 6ffc483

Please sign in to comment.