-
Notifications
You must be signed in to change notification settings - Fork 99
Documenting the external audit of the smart contract #135
Description
Scope:
- RaidenMicroTransferChannels contract: https://github.com/raiden-network/microraiden/blob/master/contracts/contracts/RaidenMicroTransferChannels.sol
- MicroRaidenEIP712Helper contract: https://github.com/raiden-network/microraiden/blob/master/contracts/contracts/MicroRaidenEIP712Helper.sol
- ECVerify library: https://github.com/raiden-network/microraiden/blob/master/contracts/contracts/lib/ECVerify.sol
- Token.sol: https://github.com/raiden-network/microraiden/blob/master/contracts/contracts/Token.sol
Outcome:
- redundant: either
tokenortoken_address,isToken,prefix
fixed in Remove isToken, prefix, token_address #196
Reviewed version for issues below: https://github.com/raiden-network/microraiden/tree/81920e4162da8b00ba54212de619668d42c11120
- tl;dr In this contract, the sender needs to fully trust the owner.
Owner can be malicious / his account can be compromised and changeMicroRaidenEIP712Helper.getMessageHashby deploying another contract with malicious code and changing the address inRaidenMicroTransferChannelswithsetEip712HelperContract.
Possible scenarios:
getMessageHashis changed -> channels are locked, because the sender's signature from_balance_msg_sigcannot be recovered.- owner colludes with 1 or > receivers to modify the function so that they can get more tokens out of the channels than they are owed (amount of tokens limited by the actual channel deposit)
The receiver can use any hash of a signed message from the sender, to be returned in a hardcoded way in the EIP712 helper.
(e.g. : in RaidenMicroTransferChannels.cooperativeClose -> verifyBalanceProof, getMessageHash can return the hash corresponding to _balance - 100 instead of _balance. This means the receiver can provide an authentic _balance_msg_sig with balance = _balance - 100, but use _balance as an argument for cooperativeClose.)
Possible solution:
Adding a function to change the owner would be important. Specially if the owner address gets compromised.
I would put another role. eip712updater so you can set it to 0x0 when the eip712 standard is stabilized. And still maintain the option to setLatestVersionAddress. Needed methods: changeOwner, changeEip712updater .. In the constructors both vars can be set to msg.sender
Having owner and eip712updater diferently allows to cancel the possibility to change the eip712 helper and still update the version.
IMO, if there is an eip712 update, I would deploy a full new contract.
-
This smart contract has a huge risk that people just do a normal
transferto this contract of pure ERC20 tokens thinking they were ERC223 tokens. The consequence of that is that he just burn the tokens.
So, I would add a protection where an owner could remove any foreign tokens sent erroneously to this contract. and also this extra tokens that are there but should not be there. This last will require to add a global variable with the tokens that is supposed to have the contract. This variable will be updated every time a channel is created, toped, or settled. -
An event for setLatestVersionAddress and setEip712HelperContract would be good.
-
I agree with Lefteris about using ENS for last version. This is much more easy and you remove the need for the owner here.
-
In
I would addevent ChannelCreated( _open_block_numberlike other ovents. I know it’s not stricly necessary, but standarizes the format of the events. -
require(_challenge_period > 500) -
require(Token(_token).totalSupply() > 0)inRaidenMicroTransferChannelsconstructor, to check if it is really a token. -
Side comment: I would expect that for EIP223 the data follows the solidity convention: 4 bytes (method selector) and then the params. In this case you would not have to distinguish the function by the length of the data which is not very elegant. ( but more optimal )
// topUp - receiver address (20 bytes) + open_block_number (4 bytes) = 24 bytes -
Why do you don’t use eip712 for
_closing_sig?