Skip to content

feat: add erc4626 dummy delayed strategy#89

Draft
0xKoaj wants to merge 5 commits intomainfrom
feat/bly-3229
Draft

feat: add erc4626 dummy delayed strategy#89
0xKoaj wants to merge 5 commits intomainfrom
feat/bly-3229

Conversation

@0xKoaj
Copy link
Contributor

@0xKoaj 0xKoaj commented Oct 22, 2024

No description provided.

@linear
Copy link

linear bot commented Oct 22, 2024

@github-actions
Copy link

github-actions bot commented Oct 22, 2024

Slither report

THIS CHECKLIST IS NOT COMPLETE. Use --show-ignored-findings to show all the results.
Summary

missing-zero-check

Impact: Low
Confidence: Medium

constructor(IGlobalEarnRegistry _registry, address farmToken_, uint256 delay_) {

calls-loop

Impact: Low
Confidence: Medium

function withdrawableFunds(uint256 positionId, address) external view override returns (uint256 withdrawableAmount) {
Request[] memory requests = _pendingWithdrawals[positionId];
// slither-disable-next-line incorrect-equality
if (requests.length == 0) {
return 0;
}
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline <= block.timestamp) {
withdrawableAmount += IERC4626(_farmToken).previewRedeem(requests[i].amount);
}
}
}

function withdraw(
uint256 positionId,
address,
address recipient
)
external
override
onlyManager
returns (uint256 withdrawn, uint256 stillPending)
{
Request[] memory requests = _pendingWithdrawals[positionId];
if (requests.length == 0) {
return (0, 0);
}
uint256 numberOfRequestsPending;
uint256 farmTokenAmountToWithdraw;
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline > block.timestamp) {
stillPending += IERC4626(_farmToken).previewRedeem(requests[i].amount);
if (numberOfRequestsPending != i) {
requests[numberOfRequestsPending] = requests[i];
}
++numberOfRequestsPending;
} else {
farmTokenAmountToWithdraw += requests[i].amount;
}
}
if (numberOfRequestsPending != requests.length) {
// Resize the array
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(requests, numberOfRequestsPending)
}
}
_pendingWithdrawals[positionId] = requests;
withdrawn = IERC4626(_farmToken).redeem(farmTokenAmountToWithdraw, recipient, address(this));
}

function estimatedPendingFunds(uint256 positionId, address) external view override returns (uint256 pendingAmount) {
Request[] memory requests = _pendingWithdrawals[positionId];
// slither-disable-next-line incorrect-equality
if (requests.length == 0) {
return 0;
}
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline > block.timestamp) {
pendingAmount += IERC4626(_farmToken).previewRedeem(requests[i].amount);
}
}
}

timestamp

Impact: Low
Confidence: Medium

function withdraw(
uint256 positionId,
address,
address recipient
)
external
override
onlyManager
returns (uint256 withdrawn, uint256 stillPending)
{
Request[] memory requests = _pendingWithdrawals[positionId];
if (requests.length == 0) {
return (0, 0);
}
uint256 numberOfRequestsPending;
uint256 farmTokenAmountToWithdraw;
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline > block.timestamp) {
stillPending += IERC4626(_farmToken).previewRedeem(requests[i].amount);
if (numberOfRequestsPending != i) {
requests[numberOfRequestsPending] = requests[i];
}
++numberOfRequestsPending;
} else {
farmTokenAmountToWithdraw += requests[i].amount;
}
}
if (numberOfRequestsPending != requests.length) {
// Resize the array
// solhint-disable-next-line no-inline-assembly
assembly {
mstore(requests, numberOfRequestsPending)
}
}
_pendingWithdrawals[positionId] = requests;
withdrawn = IERC4626(_farmToken).redeem(farmTokenAmountToWithdraw, recipient, address(this));
}

function estimatedPendingFunds(uint256 positionId, address) external view override returns (uint256 pendingAmount) {
Request[] memory requests = _pendingWithdrawals[positionId];
// slither-disable-next-line incorrect-equality
if (requests.length == 0) {
return 0;
}
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline > block.timestamp) {
pendingAmount += IERC4626(_farmToken).previewRedeem(requests[i].amount);
}
}
}

function withdrawableFunds(uint256 positionId, address) external view override returns (uint256 withdrawableAmount) {
Request[] memory requests = _pendingWithdrawals[positionId];
// slither-disable-next-line incorrect-equality
if (requests.length == 0) {
return 0;
}
for (uint256 i; i < requests.length; ++i) {
if (requests[i].deadline <= block.timestamp) {
withdrawableAmount += IERC4626(_farmToken).previewRedeem(requests[i].amount);
}
}
}

naming-convention

Impact: Informational
Confidence: High

function ERC4626Vault() public view virtual override returns (IERC4626) {
return IERC4626(_farmToken);
}

@0xKoaj 0xKoaj requested a review from 0xsambugs October 22, 2024 19:05
Copy link
Collaborator

@0xsambugs 0xsambugs left a comment

Choose a reason for hiding this comment

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

Great work!

}
}
_pendingWithdrawals[positionId] = requests;
IERC4626(_farmToken).withdraw(withdrawn, recipient, address(this));
Copy link
Collaborator

Choose a reason for hiding this comment

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

This might fail, due to precision. I would add up all shares that are able to be withdrawn in one int, and then call redeem here (and assign he result to withdrawn)

Comment on lines +214 to +222
IERC4626 vault = ERC4626Vault();
// Note: we assume params are consistent and valid because they were validated by the EarnVault
IERC20(address(vault)).safeTransfer(
address(_connector_delayedWithdrawalAdapter(tokens[0])), vault.previewWithdraw(toWithdraw[0])
);

_connector_delayedWithdrawalAdapter(tokens[0]).initiateDelayedWithdrawal(positionId, tokens[0], toWithdraw[0]);

withdrawalTypes = _connector_supportedWithdrawals();
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Correct me if I'm wrong, but I think you also need to pass the amount of shares (not assets) to initiateDelayedWithdrawal

Suggested change
IERC4626 vault = ERC4626Vault();
// Note: we assume params are consistent and valid because they were validated by the EarnVault
IERC20(address(vault)).safeTransfer(
address(_connector_delayedWithdrawalAdapter(tokens[0])), vault.previewWithdraw(toWithdraw[0])
);
_connector_delayedWithdrawalAdapter(tokens[0]).initiateDelayedWithdrawal(positionId, tokens[0], toWithdraw[0]);
withdrawalTypes = _connector_supportedWithdrawals();
}
IERC4626 vault = ERC4626Vault();
// Note: we assume params are consistent and valid because they were validated by the EarnVault
uint256 shares = vault.previewWithdraw(toWithdraw[0]);
IERC20(address(vault)).safeTransfer(
address(_connector_delayedWithdrawalAdapter(tokens[0])), shares)
);
_connector_delayedWithdrawalAdapter(tokens[0]).initiateDelayedWithdrawal(positionId, tokens[0], shares);
withdrawalTypes = _connector_supportedWithdrawals();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants