Closed c4-bot-10 closed 2 months ago
Good quality report, provisionally marking as satisfactory
3docSec marked the issue as satisfactory
3docSec marked the issue as selected for report
as EIP712 doc mentioned: The dynamic values bytes and string are encoded as a keccak256 hash of their contents.
and also in the doc example bytes32 constant MAIL_TYPEHASH = keccak256( "Mail(address from,address to,string contents)");
this type hash should not be bytes32
since type of field is string
I agree with the sponsor. The EIP-712 docs make an example where:
bytes32 constant MAIL_TYPEHASH = keccak256("Mail(address from,address to,string contents)");
and then encodes the object hash as follows:
function hashStruct(Mail memory mail) pure returns (bytes32 hash) {
return keccak256(abi.encode(
MAIL_TYPEHASH,
mail.from,
mail.to,
keccak256(mail.contents)
));
}
which is the same that the highlighted code does: declaring it as string in the TYPEHASH
definition, then encoding it as bytes32
output by keccak256
of the string value.
3docSec marked the issue as unsatisfactory: Insufficient proof
Lines of code
https://github.com/code-423n4/2024-06-krystal-defi/blob/f65b381b258290653fa638019a5a134c4ef90ba8/src/StructHash.sol#L86-L108 https://github.com/code-423n4/2024-06-krystal-defi/blob/f65b381b258290653fa638019a5a134c4ef90ba8/src/EIP712.sol#L24-L28
Vulnerability details
Proof of Concept
The
StructHash.sol
library is used to enforce normal hashing of the struct values for different action types and these hashes are to then be used in order core instances of the KrystalDefi protocol.Going through the library, we can see that whenever a hashing is to be done for any action the helper
_hash()
function returns the keccakked abi.encoded data, see an example in regards to theAutoCompoundAction_TYPEHASH
.Issue however is that where as this is rightly done in most instances, it seems to be wrongly implemented for rebalance conditioning and normal order typehashing, see https://github.com/code-423n4/2024-06-krystal-defi/blob/f65b381b258290653fa638019a5a134c4ef90ba8/src/StructHash.sol#L86-L108
Evidently, the
RebalanceCondition_TYPEHASH
expects the type to be attached as a string and not bytes32, however as hinted by the @audit tag, the encode keccak hashes theobj._type
which then causes the value used to be a bytes32 instead of a string.Now using any Keccak 256 online checker, we would see that protocol rightly attaches the typehash to the RebalanceCondition, i.e below we query to get the typehash while having the type attached as a string, which returns
0x79a6efb57bb0d511e670abb964181b04730ebe3a5fd187d05341eeb9288deef8
:However if we use the same tool and instead pass in thetype attached as a bytes32 value, we instead get a whole different typehash, i.e
0xd3d30349ea1059164f17733846216e64f2d4a39c3c19b9812099f3d03a3492c6
which showcases that the wrong typehash is being used for the Reblancing conditions and as such would translate to protocol not being compatible with the intended inherited implementation of EIP 712 and cause issues with integrators who correctly sign their orders.Impact
As hinted under the Proof of Concept the Rebalancing condition and Order have an incorrect typehash since an extra keccak of the type is being done, which would lead to issues when attempting to vaildate the signatures applied in the snippet below since valid signatures would be assumed as invalid in the in-scope EIP712.sol https://github.com/code-423n4/2024-06-krystal-defi/blob/f65b381b258290653fa638019a5a134c4ef90ba8/src/EIP712.sol#L24-L28
And extensively when validating orders in V3Automation.sol.
Tool Used
Recommended Mitigation Steps
Modify the structure typehash to point to the correct structures, i.e modify the typehashes to expect a
bytes32
for the order type and not a string. So0xd3d30349ea1059164f17733846216e64f2d4a39c3c19b9812099f3d03a3492c6
should be used for the RebalanceCondition, pseudo fixes:And a similar fix should be applied to the Order_TYPEHASH.
Assessed type
Context