Powerful Honeysuckle Anteater
Medium
For CDS withdraw we don't link a signature to a specific address, which leads to nonce not being able to be distinguished
When doing a CDS withdraw we perform signature verification in CDS.sol
in verify()
, however, there isn't an address that's passed in, so anyone could use signatures from anyone else and potentially get better excessProfitCumulativeValue
.
Not having an address linked to a signature, will result in DoS due to signature frontrunning. Also, anyone could use the signatures of others, which have better excessProfitCumulativeValue
.
Reference CDS.sol#L878-L916
function _verify(FunctionName functionName, uint256 excessProfitCumulativeValue, uint256 nonce, bytes memory odosExecutionData, bytes memory signature) private view returns (bool) {
bytes32 digest;
if (functionName == FunctionName.CDS_WITHDRAW) {
digest = _hashTypedDataV4(
keccak256(
abi.encode(
keccak256(
"Permit(uint256 excessProfitCumulativeValue,uint256 nonce)"
),
excessProfitCumulativeValue,
@>> nonce // We only pass nonce
)
)
);
} else if (functionName == FunctionName.BORROW_WITHDRAW) {
....
}
address signer = ECDSA.recover(digest, signature);
bytes32 hashedSigner = keccak256(abi.encodePacked(signer));
if (hashedSigner == hashedAdminTwo) {
return true;
} else {
return false;
}
}
- User A intends to make a withdrawal.
- User B can front-run User A by capturing their signature and withdrawing User A's position. This would result in a revert, as nonce checks would fail. (It should be noted that currently nonces are not checked, which is a separate issue, and fixing that would not resolve this issue due to a different root cause.)
uint256 currentValue = cdsAmountToReturn(
msg.sender,
index,
omniChainData.cumulativeValue,
omniChainData.cumulativeValueSign,
@>> excessProfitCumulativeValue
) - 1;
- Adversary can front-run Users and DoS their ability to withdraw.
- Adversary could get a better excessProfitCumulativeValue from another user, by frontrunning it.
Pass an address and verify it in the signature.