Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Update AccountsStrategy._payForGasWithAccountBalance to accept gas percentage to pay from liquid balance #289

Closed
wants to merge 7 commits into from
64 changes: 40 additions & 24 deletions contracts/core/accounts/facets/AccountsStrategy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ contract AccountsStrategy is
AccountStorage.State storage state = LibAccounts.diamondStorage();
AccountStorage.Endowment storage tempEndowment = state.ENDOWMENTS[id];

require(
investRequest.lockAmt > 0 || investRequest.liquidAmt > 0,
"Must invest at least one of Locked/Liquid"
);

// check if the msg sender is either the owner or their delegate address and
// that they have the power to manage the investments for an account balance
if (investRequest.lockAmt > 0) {
Expand Down Expand Up @@ -98,6 +103,8 @@ contract AccountsStrategy is
"Token not approved"
);

uint256 investAmt = investRequest.lockAmt + investRequest.liquidAmt;

uint32[] memory accts = new uint32[](1);
accts[0] = id;

Expand All @@ -115,16 +122,13 @@ contract AccountsStrategy is
});
bytes memory packedPayload = RouterLib.packCallData(payload);

IERC20(tokenAddress).safeTransfer(
thisNetwork.router,
(investRequest.lockAmt + investRequest.liquidAmt)
);
IERC20(tokenAddress).safeTransfer(thisNetwork.router, investAmt);
IVault.VaultActionData memory response = IRouter(thisNetwork.router).executeWithTokenLocal(
state.config.networkName,
AddressToString.toString(address(this)),
packedPayload,
investRequest.token,
(investRequest.lockAmt + investRequest.liquidAmt)
investAmt
);

if (response.status == IVault.VaultActionStatus.SUCCESS) {
Expand Down Expand Up @@ -161,6 +165,7 @@ contract AccountsStrategy is
tokenAddress,
investRequest.lockAmt,
investRequest.liquidAmt,
(investRequest.liquidAmt * LibAccounts.PERCENT_BASIS) / investAmt,
(investRequest.gasFee - gasFwdGas)
);
}
Expand All @@ -171,21 +176,18 @@ contract AccountsStrategy is
AddressToString.toString(network.router),
packedPayload,
investRequest.token,
(investRequest.lockAmt + investRequest.liquidAmt),
investAmt,
tokenAddress,
investRequest.gasFee,
state.ENDOWMENTS[id].gasFwd
);
IERC20(tokenAddress).safeApprove(
thisNetwork.axelarGateway,
(investRequest.lockAmt + investRequest.liquidAmt)
);
IERC20(tokenAddress).safeApprove(thisNetwork.axelarGateway, investAmt);
IAxelarGateway(thisNetwork.axelarGateway).callContractWithToken(
stratParams.network,
AddressToString.toString(network.router),
packedPayload,
investRequest.token,
(investRequest.lockAmt + investRequest.liquidAmt)
investAmt
);
state.STATES[id].balances.locked[tokenAddress] -= investRequest.lockAmt;
state.STATES[id].balances.liquid[tokenAddress] -= investRequest.liquidAmt;
Expand All @@ -204,6 +206,11 @@ contract AccountsStrategy is
AccountStorage.State storage state = LibAccounts.diamondStorage();
AccountStorage.Endowment storage tempEndowment = state.ENDOWMENTS[id];

require(
redeemRequest.lockAmt > 0 || redeemRequest.liquidAmt > 0,
"Must redeem at least one of Locked/Liquid"
);

// check if the msg sender is either the owner or their delegate address and
// that they have the power to manage the investments for an account balance
if (redeemRequest.lockAmt > 0) {
Expand Down Expand Up @@ -292,11 +299,14 @@ contract AccountsStrategy is
redeemRequest.gasFee
);
if (gasFwdGas < redeemRequest.gasFee) {
uint256 gasPercentFromLiq = (redeemRequest.liquidAmt * LibAccounts.PERCENT_BASIS) /
(redeemRequest.liquidAmt + redeemRequest.lockAmt);
_payForGasWithAccountBalance(
id,
tokenAddress,
redeemRequest.lockAmt,
redeemRequest.liquidAmt,
id,
tokenAddress,
0, // redeeming, no tokens will be sent
0,
gasPercentFromLiq,
(redeemRequest.gasFee - gasFwdGas)
);
}
Expand Down Expand Up @@ -420,11 +430,13 @@ contract AccountsStrategy is
redeemAllRequest.gasFee
);
if (gasFwdGas < redeemAllRequest.gasFee) {
uint256 gasPercentFromLiq = 50;
_payForGasWithAccountBalance(
id,
tokenAddress,
1, // Split evenly
1,
id,
tokenAddress,
0, // redeeming, no tokens will be sent
0,
gasPercentFromLiq,
(redeemAllRequest.gasFee - gasFwdGas)
);
}
Expand Down Expand Up @@ -563,26 +575,30 @@ contract AccountsStrategy is
* We split the gas payment proprotionally between locked and liquid if possible and
* use liquid funds for locked gas needs, but not the other way around in the case of a shortage.
* Revert if the combined balances of the account cannot cover both the investment request and the gas payment.
* @param id Endowment ID
* @param token Token address
* @param lockAmt Amount needed from locked balance
* @param liqAmt Amount needed from liquid balance
* @param gasPercentFromLiq Percentage of gas to pay from liquid portion
* @param gasRemaining Amount of gas to be payed from locked & liquid balances
*/
function _payForGasWithAccountBalance(
uint32 id,
address token,
uint256 lockAmt,
uint256 liqAmt,
uint256 gasPercentFromLiq,
uint256 gasRemaining
) internal {
AccountStorage.State storage state = LibAccounts.diamondStorage();
uint256 lockBal = state.STATES[id].balances.locked[token];
uint256 liqBal = state.STATES[id].balances.liquid[token];
uint256 sendAmt = lockAmt + liqAmt;

// Split gas proportionally between liquid and lock amts
uint256 liqGas = (gasRemaining * ((liqAmt * LibAccounts.BIG_NUMBA_BASIS) / sendAmt)) /
LibAccounts.BIG_NUMBA_BASIS;
uint256 liqGas = (gasRemaining * gasPercentFromLiq) / LibAccounts.PERCENT_BASIS;
uint256 lockGas = gasRemaining - liqGas;

uint256 lockNeed = lockGas + lockAmt;
uint256 liqNeed = liqGas + liqAmt;
uint256 lockNeed = lockGas + lockAmt;

// Cases:
// 1) lockBal and liqBal each cover the respective needs
Expand Down
Loading