DMDcoin / diamond-contracts-claiming

claiming contracts
0 stars 2 forks source link

[L-05] Use of RIPEMD-160 Precompile in publicKeyToDMDAddress Function May Not Be Universally Compatible #60

Open softstackio opened 1 week ago

softstackio commented 1 week ago

Description: The publicKeyToDMDAddress function in the ClaimContract uses the ripemd160 hash function, which is implemented as a precompile contract in Ethereum at address(2). This function is used to generate a Bitcoin-style address from ECDSA public key coordinates. However, the availability and behavior of this precompile may not be consistent across all Ethereum-compatible chains or Layer 2 solutions.

The use of ripemd160 assumes that:

  1. The precompile contract at address(2) is available on the target chain.
  2. The precompile correctly calculates and returns the RIPEMD-160 hash of the provided input. These assumptions may not hold true for all chains where this contract might be deployed, potentially leading to unexpected behavior or deployment failures.

Impact: If deployed on a chain where the RIPEMD-160 precompile is not available or functions differently, the publicKeyToDMDAddress function may:

  1. Fail to execute, causing transactions to revert.
  2. Produce incorrect Bitcoin-style addresses, leading to potential loss of funds or inability to claim tokens.
  3. Increase gas costs if the precompile is implemented differently on the target chain.

Recommendation:

  1. Verify the availability and correctness of the RIPEMD-160 precompile on all target chains before deployment.
  2. Consider implementing a fallback pure Solidity version of RIPEMD-160 that can be used if the precompile is not available.
  3. Add a configuration option to switch between the precompile and a pure Solidity implementation based on the target chain.
  4. Document clearly which chains have been verified to support the required precompiles.
  5. If possible, consider using alternative hash functions that are more universally supported across different chains.

Example of a potential fallback approach:

function publicKeyToDMDAddress(bytes32 _publicKeyX, bytes32 _publicKeyY)
public view returns (bytes20 rawBtcAddress) {
   bytes memory input = abi.encodePacked(
       sha256(abi.encodePacked((uint256(_publicKeyY) & 1) == 0 ? 0x02 :
0x03, _publicKeyX))
   );
   if (isPrecompileAvailable(address(2))) {
       return ripemd160(input);
   } else {
       return fallbackRIPEMD160(input);
} }
function isPrecompileAvailable(address precompile) internal view returns
(bool) {
   uint256 codeSize;
   assembly {
       codeSize := extcodesize(precompile)
   }
   return codeSize > 0;
}
function fallbackRIPEMD160(bytes memory input) internal pure returns
(bytes20) {
// Implement a pure Solidity version of RIPEMD-160 here
   // This is a placeholder and needs to be properly implemented
   revert("Fallback RIPEMD-160 not implemented");
}