Skip links
RCN Network

RCN Smart Contracts Audit v2

Summary

The smart contracts that have been audited were taken from the RCN repository at: https://github.com/ripio/rcn-network/tree/v2. The audit is based on the commit 3ded36151ad55543d16c354e70161852de4061d0, which was updated to reflect changes at: 052e5fd4d77301e854d0ecdaadbd785dd91950ce.

The audited files are:

  • NanoLoanEngine.sol: Lending engine
  • examples/BasicScoreProvider.sol: Example
  • examples/ReferenceCosigner.sol: Example of a cosigner
  • examples/ReferenceOracle.sol: Example of an oracle
  • interfaces/Cosigner.sol: Interface of cosigners
  • interfaces/Engine.sol: Interface of loan engine
  • interfaces/ERC721.sol: Interface ERC721 non-fungible token
  • interfaces/Oracle.sol: Interface of oracles
  • interfaces/Token.sol: Interface of ERC20 fungible token
  • utils/BytesUtils.sol: Utility to access bytes array
  • utils/Delegable.sol: Permission with valid date ranges for contract users
  • utils/Ownable.sol: Defines a contract’s owner
  • utils/RpSafeMath.sol: Math operations with overflow check
  • utils/SimpleDelegable.sol: Simple permission for contract users
  • utils/TokenLockable.sol: Withdrawal of arbitrary tokens, with lock/unlock operations

The contracts are RCN lending protocol implementations. RCN is a protocol based on smart contracts which standardize credit lending through blockchain technology. Now, the NanoLoanEngine loans are treated as ERC721 non-fungible tokens.

We did not find any critical issues. However, there is one medium severity issue involving a function that does not validate the input data; a couple of functions can also cause problems if they are used in a contract.

Detailed findings

Medium severity

Read arbitrary data

The function readBytes32 in BytesUtil.sol reads data from memory, but it can return data past the valid length of the bytes array.

  function readBytes32(bytes data, uint256 index) internal constant returns (bytes32 o) {
       assembly {
           o := mload(add(data, add(32, mul(32, index))))
       }
   }

The assembly function mload reads 32 bytes from an arbitrary memory direction, it doesn’t check that the direction is valid.

We recommend that the calculated memory direction is inside the data.

For example, in the function requestCosign in ReferenceCosigner.sol it uses readBytes32 from a user-supplied bytes array. But it does not check that the data supplied is of the expected size.

This issue was fixed at commit 35b79591c13bf72fc6a0967901b241e21236927e.

Minor severity

Risk of running out of gas if large iterations take place

The functions tokenOfOwnerByIndex and tokensOfOwner can potentially iterate over all the loans in the contract.

           uint256 totalLoans = totalSupply();
           uint256 loanId;

           // This can iterate over all created loans
           for (loanId = 0; loanId <= totalLoans; loanId++) {
               ..
           }

These functions are not used by other contracts in the project, but if they are used by a third party contract there is the possibility of a lock caused by consuming more gas than the current block gas limit.

It was reported to us these functions are not designed to be used from other contracts and they will document the risk out of gas due to high gas consumption.

Observations

  • Use of the constant modifier is deprecated in favor of view or pure in recent versions of solidity.

This was fixed at commit 047605361e3f1f95db2984cdd15921d1684ac2cd

Conclusion

We did not find any serious issue in the analyzed contracts. However, we found one medium severity and one minor issue with a couple of functions.

The medium severity issue was caused by a function that did not validate input data and could be forced to return erroneous data. But it should be easy to fix to verify the length of the input. The minor issues can cause problems only if there are lots of loans and if they are called from within a badly programmed contract.

Overall: We found that the contracts are well written and extensively documented. Also, we noticed while we were performing the audit, that RCN was updating continuously to comply with new solidity compiler version once there was a new version released.

Do you want to know what is Coinfabrik Auditing Process?

Check our A-Z Smart Contract Audit Guide or you could request a quote for your project.