-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2024-01-telcoin
71 lines (58 loc) · 2.86 KB
/
2024-01-telcoin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# Telcoin
## Contest Summary
Code under review: [2024-01-telcoin](https://github.com/sherlock-audit/2024-01-telcoin-judging/issues) (907 nSLOC)
Contest Page: [telcoin-contest](https://audits.sherlock.xyz/contests/156)
# Findings
## [H-1] User lose tokens when claim deposit or redeem within the same epoch
### Summary
Amphor protocol proposed few features of the ERC-4626 Tokenized Vaults system. When the vault is closed, the user can submit a request, and should not be able to claim deposit or redeem until the next epoch. However, it is possible, causing users to lose their funds.
### Vulnerability Detail
The functions for previewClaimDeposit and previewClaimRedeem calls _convertToAssets and _convertToShares in AsyncSynthVault.sol returns 0 for assets and shares if the function is called within the same epoch.
```solidity
// Both `previewClaimDeposit and previewClaimRedeem` contains the logic:
if (isCurrentEpoch(requestId)) {
return 0;
}
```
```solidity
//AsyncSynthVault.sol
function _claimDeposit(
address owner,
address receiver
)
internal
returns (uint256 shares)
{
shares = previewClaimDeposit(owner); //0
uint256 lastRequestId = lastDepositRequestId[owner];
uint256 assets = epochs[lastRequestId].depositRequestBalance[owner];
epochs[lastRequestId].depositRequestBalance[owner] = 0;
_update(address(claimableSilo), receiver, shares); // update receiver to have 0 shares
emit ClaimDeposit(lastRequestId, owner, receiver, assets, shares);
}
function _claimRedeem(
address owner,
address receiver
)
internal
whenNotPaused
returns (uint256 assets)
{
assets = previewClaimRedeem(owner); // return 0 if is current epoch
uint256 lastRequestId = lastRedeemRequestId[owner];
uint256 shares = epochs[lastRequestId].redeemRequestBalance[owner];
epochs[lastRequestId].redeemRequestBalance[owner] = 0;
_asset.safeTransferFrom(address(claimableSilo), address(this), assets); // transfer 0
_asset.transfer(receiver, assets); // transfer 0
emit ClaimRedeem(lastRequestId, owner, receiver, assets, shares);
}
```
### Impact
The requested assets or shares that are claimed within the same epoch will be stuck in claimable silo, causing wrong accounting of assets and shares that are locked. Furthermore causing the users to not be able to successfully get their assets or shares, instead, they will have a balance of 0 assets and shares.
### Code Snippet
https://github.com/sherlock-audit/2024-03-amphor/blob/main/asynchronous-vault/src/AsyncSynthVault.sol#L749
https://github.com/sherlock-audit/2024-03-amphor/blob/main/asynchronous-vault/src/AsyncSynthVault.sol#L766
### Tool used
Manual Review
### Recommendation
Ensure that the users cannot redeem or claim before the next epoch.