Powerful Honeysuckle Anteater
Medium
When doing a Borrower withdraw we perform signature verification in CDS.sol
in verify()
and we pass the ODOS data, which is later submitted to the ODOS router.
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
)
)
);
@>> } else if (functionName == FunctionName.BORROW_WITHDRAW) {
digest = _hashTypedDataV4(
@>> keccak256(abi.encode(keccak256("OdosPermit(bytes odosExecutionData)"), odosExecutionData))
);
}
address signer = ECDSA.recover(digest, signature);
bytes32 hashedSigner = keccak256(abi.encodePacked(signer));
@>> if (hashedSigner == hashedAdminTwo) {
return true;
} else {
return false;
}
}
https://optimistic.etherscan.io/address/0xca423977156bb05b13a2ba3b76bc5419e2fe9680#code - this is the odos contract.
Odos permits are handled here.
function swapPermit2(
permit2Info memory permit2,
swapTokenInfo memory tokenInfo,
bytes calldata pathDefinition,
address executor,
uint32 referralCode
)
external
returns (uint256 amountOut)
{
ISignatureTransfer(permit2.contractAddress).permitTransferFrom(
@>> ISignatureTransfer.PermitTransferFrom(
ISignatureTransfer.TokenPermissions(
tokenInfo.inputToken,
tokenInfo.inputAmount
),
permit2.nonce,
permit2.deadline
),
ISignatureTransfer.SignatureTransferDetails(
tokenInfo.inputReceiver,
tokenInfo.inputAmount
),
msg.sender,
permit2.signature
);
return _swap(
tokenInfo,
pathDefinition,
executor,
referralCode
);
}
ODOS makes sure that nonces cannot be reused, however this opens the possibility for someone to frontrun a withdraw of a user and use their ODOS data.
- User A (borrower) submits a transaction to withdraw his position
- User B frontruns User A and withdraws another position using User A's
odosAssembledData
This would result in a Dos of User A.
No Response