Skip to content
Open
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
177 changes: 117 additions & 60 deletions src/contracts/Qswap.h
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ struct QSWAP : public ContractBase
}
}

// no available solt for new pool
// no available slot for new pool
if (locals.poolSlot == -1)
{
return;
Expand Down Expand Up @@ -687,7 +687,7 @@ struct QSWAP : public ContractBase
}
}

// no available solt for new pool
// no available slot for new pool
if (locals.poolSlot == -1)
{
return;
Expand Down Expand Up @@ -750,7 +750,7 @@ struct QSWAP : public ContractBase
}
}

// no available solt for new pool
// no available slot for new pool
if (locals.poolSlot == -1)
{
return;
Expand Down Expand Up @@ -819,7 +819,7 @@ struct QSWAP : public ContractBase
}
}

// no available solt for new pool
// no available slot for new pool
if (locals.poolSlot == -1)
{
return;
Expand Down Expand Up @@ -983,7 +983,7 @@ struct QSWAP : public ContractBase
}
}

// no available solt for new pool
// no available slot for new pool
if (locals.poolSlot == -1)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
Expand Down Expand Up @@ -1498,6 +1498,8 @@ struct QSWAP : public ContractBase

uint128 feeToQx;
uint128 feeToBurn;

sint64 totalFee;
};

// given an input qu amountIn, only execute swap in case (amountOut >= amountOutMin)
Expand Down Expand Up @@ -1612,7 +1614,13 @@ struct QSWAP : public ContractBase
state.investRewardsEarnedFee += locals.feeToInvestRewards.low;
state.burnEarnedFee += locals.feeToBurn.low;

locals.poolBasicState.reservedQuAmount += locals.quAmountIn - sint64(locals.feeToShareholders.low) - sint64(locals.feeToQx.low) - sint64(locals.feeToInvestRewards.low) - sint64(locals.feeToBurn.low);
locals.totalFee = sint64(locals.feeToShareholders.low) + sint64(locals.feeToQx.low) + sint64(locals.feeToInvestRewards.low) + sint64(locals.feeToBurn.low);
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 you should move this check to before the transfer of assets (~line 1592). With the version right now it can happen that the assets are transferred and the caller is reimbursed.

if (locals.quAmountIn < locals.totalFee)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
return;
}
locals.poolBasicState.reservedQuAmount += locals.quAmountIn - locals.totalFee;
locals.poolBasicState.reservedAssetAmount -= locals.assetAmountOut;
state.mPoolBasicStates.set(locals.poolSlot, locals.poolBasicState);

Expand Down Expand Up @@ -1642,6 +1650,8 @@ struct QSWAP : public ContractBase
uint128 feeToShareholders;
uint128 feeToQx;
uint128 feeToBurn;

sint64 totalFee;
};

// https://docs.uniswap.org/contracts/v2/reference/smart-contracts/router-02#swaptokensforexacttokens
Expand Down Expand Up @@ -1708,21 +1718,7 @@ struct QSWAP : public ContractBase
);

// above call overflow
if (locals.quAmountIn == -1)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
return;
}

// not enough qu amountIn
if (locals.quAmountIn > qpi.invocationReward())
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
return;
}

// not meet user's amountIn limit
if (locals.quAmountIn > qpi.invocationReward())
if (locals.quAmountIn == -1 || locals.quAmountIn > qpi.invocationReward())
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
return;
Expand Down Expand Up @@ -1773,7 +1769,13 @@ struct QSWAP : public ContractBase
state.investRewardsEarnedFee += locals.feeToInvestRewards.low;
state.burnEarnedFee += locals.feeToBurn.low;

locals.poolBasicState.reservedQuAmount += locals.quAmountIn - sint64(locals.feeToShareholders.low) - sint64(locals.feeToQx.low) - sint64(locals.feeToInvestRewards.low) - sint64(locals.feeToBurn.low);
locals.totalFee = sint64(locals.feeToShareholders.low) + sint64(locals.feeToQx.low) + sint64(locals.feeToInvestRewards.low) + sint64(locals.feeToBurn.low);
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here, move this to before transfer

if (locals.quAmountIn < locals.totalFee)
{
qpi.transfer(qpi.invocator(), locals.quAmountIn);
return;
}
locals.poolBasicState.reservedQuAmount += locals.quAmountIn - locals.totalFee;
locals.poolBasicState.reservedAssetAmount -= input.assetAmountOut;
state.mPoolBasicStates.set(locals.poolSlot, locals.poolBasicState);

Expand Down Expand Up @@ -1805,6 +1807,8 @@ struct QSWAP : public ContractBase
uint128 feeToShareholders;
uint128 feeToQx;
uint128 feeToBurn;

sint64 totalFee;
};

// given an amount of asset swap in, only execute swaping if quAmountOut >= input.amountOutMin
Expand Down Expand Up @@ -1960,11 +1964,15 @@ struct QSWAP : public ContractBase

// update pool states
locals.poolBasicState.reservedAssetAmount += input.assetAmountIn;
locals.poolBasicState.reservedQuAmount -= locals.quAmountOut;
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToShareholders.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToQx.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToInvestRewards.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToBurn.low);
locals.totalFee = locals.quAmountOut + sint64(locals.feeToShareholders.low) + sint64(locals.feeToQx.low) + sint64(locals.feeToInvestRewards.low) + sint64(locals.feeToBurn.low);
if (locals.poolBasicState.reservedQuAmount < locals.totalFee)
{
locals.poolBasicState.reservedQuAmount = 0;
}
else
{
locals.poolBasicState.reservedQuAmount -= locals.totalFee;
}
state.mPoolBasicStates.set(locals.poolSlot, locals.poolBasicState);

// Log SwapExactAssetForQu procedure
Expand Down Expand Up @@ -1994,6 +2002,8 @@ struct QSWAP : public ContractBase
uint128 feeToShareholders;
uint128 feeToQx;
uint128 feeToBurn;

sint64 totalFee;
};

PUBLIC_PROCEDURE_WITH_LOCALS(SwapAssetForExactQu)
Expand Down Expand Up @@ -2145,11 +2155,15 @@ struct QSWAP : public ContractBase

// update pool states
locals.poolBasicState.reservedAssetAmount += locals.assetAmountIn;
locals.poolBasicState.reservedQuAmount -= input.quAmountOut;
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToShareholders.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToQx.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToInvestRewards.low);
locals.poolBasicState.reservedQuAmount -= sint64(locals.feeToBurn.low);
locals.totalFee = input.quAmountOut + sint64(locals.feeToShareholders.low) + sint64(locals.feeToQx.low) + sint64(locals.feeToInvestRewards.low) + sint64(locals.feeToBurn.low);
if (locals.poolBasicState.reservedQuAmount < locals.totalFee)
{
locals.poolBasicState.reservedQuAmount = 0;
}
else
{
locals.poolBasicState.reservedQuAmount -= locals.totalFee;
}
state.mPoolBasicStates.set(locals.poolSlot, locals.poolBasicState);

// Log SwapAssetForExactQu procedure
Expand Down Expand Up @@ -2241,44 +2255,84 @@ struct QSWAP : public ContractBase
output.success = true;
}

PUBLIC_PROCEDURE(TransferShareManagementRights)
struct TransferShareManagementRights_locals
{
if (qpi.invocationReward() < QSWAP_FEE_BASE_100)
{
return ;
}
sint64 result;
sint64 reward;
sint64 refundAmount;
sint64 requiredFee;
bit success;
};

if (qpi.numberOfPossessedShares(input.asset.assetName, input.asset.issuer,qpi.invocator(), qpi.invocator(), SELF_INDEX, SELF_INDEX) < input.numberOfShares)
{
// not enough shares available
output.transferredNumberOfShares = 0;
if (qpi.invocationReward() > 0)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
}
}
else
PUBLIC_PROCEDURE_WITH_LOCALS(TransferShareManagementRights)
{
locals.reward = qpi.invocationReward();
locals.refundAmount = locals.reward;

output.transferredNumberOfShares = 0;

locals.success = false;

if (qpi.numberOfPossessedShares(
input.asset.assetName,
input.asset.issuer,
qpi.invocator(),
qpi.invocator(),
SELF_INDEX,
SELF_INDEX) >= input.numberOfShares)
{
if (qpi.releaseShares(input.asset, qpi.invocator(), qpi.invocator(), input.numberOfShares,
input.newManagingContractIndex, input.newManagingContractIndex, QSWAP_FEE_BASE_100) < 0)
locals.result = qpi.releaseShares(
input.asset,
qpi.invocator(),
qpi.invocator(),
input.numberOfShares,
input.newManagingContractIndex,
input.newManagingContractIndex,
0
);

if (locals.result != INVALID_AMOUNT)
{
// error
output.transferredNumberOfShares = 0;
if (qpi.invocationReward() > 0)
if (locals.result == 0)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward());
// success, fee = 0
locals.success = true;
}
}
else
{
// success
output.transferredNumberOfShares = input.numberOfShares;
if (qpi.invocationReward() > QSWAP_FEE_BASE_100)
else if (locals.result < 0)
{
qpi.transfer(qpi.invocator(), qpi.invocationReward() - QSWAP_FEE_BASE_100);
locals.requiredFee = -locals.result;

if (locals.reward >= locals.requiredFee)
{
locals.result = qpi.releaseShares(
input.asset,
qpi.invocator(),
qpi.invocator(),
input.numberOfShares,
input.newManagingContractIndex,
input.newManagingContractIndex,
locals.requiredFee
);

if (locals.result != INVALID_AMOUNT)
{
locals.success = true;
locals.refundAmount = locals.reward - locals.result;
}
}
}
}
}

if (locals.success)
{
output.transferredNumberOfShares = input.numberOfShares;
}

if (locals.refundAmount > 0)
{
qpi.transfer(qpi.invocator(), locals.refundAmount);
}
}

REGISTER_USER_FUNCTIONS_AND_PROCEDURES()
Expand Down Expand Up @@ -2318,6 +2372,8 @@ struct QSWAP : public ContractBase
state.qxFeeRate = 5; // 5% of swap fees to QX
state.burnFeeRate = 1; // 1% of swap fees burned

ASSERT(state.swapFeeRate < QSWAP_SWAP_FEE_BASE);
ASSERT(state.shareholderFeeRate + state.investRewardsFeeRate + state.qxFeeRate + state.burnFeeRate <= 100);
//
state.investRewardsId = ID(_V, _J, _G, _R, _U, _F, _W, _J, _C, _U, _S, _N, _H, _C, _Q, _J, _R, _W, _R, _R, _Y, _X, _A, _U, _E, _J, _F, _C, _V, _H, _Y, _P, _X, _W, _K, _T, _D, _L, _Y, _K, _U, _A, _C, _P, _V, _V, _Y, _B, _G, _O, _L, _V, _C, _J, _S, _F);
}
Expand Down Expand Up @@ -2385,6 +2441,7 @@ struct QSWAP : public ContractBase
state.burnedAmount += locals.toBurn;
}
}

PRE_ACQUIRE_SHARES()
{
output.allowTransfer = true;
Expand Down
Loading