Skip to content
This repository was archived by the owner on Mar 1, 2024. It is now read-only.

Commit 272a62b

Browse files
authored
Merge pull request #164 from maticnetwork/dev-audit-fixes
Audit fixes
2 parents 99e9006 + d5aa322 commit 272a62b

File tree

12 files changed

+31
-49
lines changed

12 files changed

+31
-49
lines changed

contracts/child/ChildERC20.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ contract ChildERC20 is BaseERC20, ERC20, ERC20Detailed {
8181
revert("Disabled feature");
8282
}
8383

84-
function transferFrom(address, address, uint256 ) public returns (bool){
84+
function transferFrom(address, address, uint256 ) public returns (bool) {
8585
revert("Disabled feature");
8686
}
8787
}

contracts/common/Registry.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ contract Registry is Ownable {
7878
}
7979

8080
function addErc20Predicate(address predicate) public onlyOwner {
81+
require(predicate != address(0x0), "Can not add null address as predicate");
8182
erc20Predicate = predicate;
8283
addPredicate(predicate, Type.ERC20);
8384
}
@@ -96,6 +97,7 @@ contract Registry is Ownable {
9697

9798
function removePredicate(address predicate) public onlyOwner
9899
{
100+
require(predicates[predicate]._type != Type.Invalid, "Predicate does not exist");
99101
delete predicates[predicate];
100102
emit PredicateRemoved(predicate, msg.sender);
101103
}

contracts/common/lib/BytesLib.sol

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pragma solidity ^0.5.2;
22

3+
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
34

45
library BytesLib {
56
function concat(
@@ -134,11 +135,13 @@ library BytesLib {
134135

135136
// Pad a bytes array to 32 bytes
136137
function leftPad(bytes memory _bytes) internal pure returns (bytes memory) {
137-
bytes memory newBytes = new bytes(32 - _bytes.length);
138+
// may underflow if bytes.length < 32. Hence using SafeMath.sub
139+
bytes memory newBytes = new bytes(SafeMath.sub(32, _bytes.length));
138140
return concat(newBytes, _bytes);
139141
}
140142

141143
function toBytes32(bytes memory b) internal pure returns (bytes32) {
144+
require(b.length >= 32, "Bytes array should atleast be 32 bytes");
142145
bytes32 out;
143146
for (uint i = 0; i < 32; i++) {
144147
out |= bytes32(b[i] & 0xFF) >> (i * 8);
@@ -155,17 +158,14 @@ library BytesLib {
155158
function fromBytes32(bytes32 x) internal pure returns (bytes memory) {
156159
bytes memory b = new bytes(32);
157160
for (uint i = 0; i < 32; i++) {
158-
b[i] = byte(uint8(uint(x) / (2**(8*(19 - i)))));
161+
b[i] = byte(uint8(uint(x) / (2**(8*(31 - i)))));
159162
}
160163
return b;
161164
}
162165

163166
function fromUint(uint256 _num) internal pure returns (bytes memory _ret) {
164-
assembly {
165-
_ret := mload(0x10)
166-
mstore(_ret, 0x20)
167-
mstore(add(_ret, 0x20), _num)
168-
}
167+
_ret = new bytes(32);
168+
assembly { mstore(add(_ret, 32), _num) }
169169
}
170170

171171
function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) {

contracts/common/lib/Common.sol

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,6 @@ library Common {
2222
return (length > 0);
2323
}
2424

25-
// convert uint256 to bytes
26-
function toBytes(uint256 _num) public pure returns (bytes memory _ret) {
27-
assembly {
28-
_ret := mload(0x10)
29-
mstore(_ret, 0x20)
30-
mstore(add(_ret, 0x20), _num)
31-
}
32-
}
33-
3425
// convert bytes to uint8
3526
function toUint8(bytes memory _arg) public pure returns (uint8) {
3627
return uint8(_arg[0]);

contracts/common/lib/Merkle.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ library Merkle {
1010
) public pure returns (bool) {
1111
bytes32 proofElement;
1212
bytes32 computedHash = leaf;
13-
uint256 len = (proof.length / 32) * 32;
13+
require(proof.length % 32 == 0, "Invalid proof length");
1414

1515
uint256 index = mainIndex;
16-
for (uint256 i = 32; i <= len; i += 32) {
16+
for (uint256 i = 32; i <= proof.length; i += 32) {
1717
assembly {
1818
proofElement := mload(add(proof, i))
1919
}

contracts/root/withdrawManager/WithdrawManager.sol

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,19 @@ contract WithdrawManager is WithdrawManagerStorage, IWithdrawManager {
128128
referenceTxData[offset + 1].toBytes() // blockProof
129129
);
130130

131+
uint256 _branchMask = branchMask.toRlpItem().toUint();
132+
require(
133+
_branchMask & 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000 == 0,
134+
"Branch mask should be 32 bits"
135+
);
131136
// ageOfInput is denoted as
132137
// 1 reserve bit (see last 2 lines in comment)
133138
// 128 bits for exitableAt timestamp
134139
// 95 bits for child block number
135140
// 32 bits for receiptPos + logIndex * MAX_LOGS + oIndex
136141
// In predicates, the exitId will be evaluated by shifting the ageOfInput left by 1 bit
137142
// (Only in erc20Predicate) Last bit is to differentiate whether the sender or receiver of the in-flight tx is starting an exit
138-
return (getExitableAt(createdAt) << 127) | (blockNumber << 32) | branchMask.toRlpItem().toUint();
143+
return (getExitableAt(createdAt) << 127) | (blockNumber << 32) | _branchMask;
139144
}
140145

141146
function startExitWithDepositedTokens(uint256 depositId, address token, uint256 amountOrToken)
@@ -248,14 +253,6 @@ contract WithdrawManager is WithdrawManagerStorage, IWithdrawManager {
248253
}
249254
}
250255

251-
function setExitNFTContract(address _nftContract)
252-
external
253-
onlyOwner
254-
{
255-
require(_nftContract != address(0));
256-
exitNft = ExitNFT(_nftContract);
257-
}
258-
259256
/**
260257
* @dev Add a state update (UTXO style input) to an exit
261258
* @param exitId Exit ID

contracts/root/withdrawManager/WithdrawManagerProxy.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ import { Registry } from "../../common/Registry.sol";
44
import { Proxy } from "../../common/misc/Proxy.sol";
55
import { WithdrawManagerStorage } from "./WithdrawManagerStorage.sol";
66
import { RootChain } from "../RootChain.sol";
7+
import { ExitNFT } from "./ExitNFT.sol";
78

89

910
contract WithdrawManagerProxy is Proxy, WithdrawManagerStorage {
10-
constructor(address _proxyTo, address _registry, address _rootChain)
11+
constructor(address _proxyTo, address _registry, address _rootChain, address _exitNft)
1112
public
1213
Proxy(_proxyTo)
1314
{
1415
registry = Registry(_registry);
1516
rootChain = RootChain(_rootChain);
17+
exitNft = ExitNFT(_exitNft);
1618
}
1719
}

contracts/staking/StakeManager.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ contract StakeManager is IStakeManager, ERC721Full, RootChainable, Lockable {
354354
uint256[] memory _validators = new uint256[](validatorThreshold);
355355
uint256 validator;
356356
uint256 k = 0;
357-
for (uint96 i = 0;i < totalSupply() ;i++) {
357+
for (uint256 i = 0; i < totalSupply() ; i++) {
358358
validator = tokenByIndex(i);
359359
if (isValidator(validator)) {
360360
_validators[k++] = validator;
@@ -506,7 +506,7 @@ contract StakeManager is IStakeManager, ERC721Full, RootChainable, Lockable {
506506
function challangeStateRootUpdate(bytes memory checkpointTx /* txData from submitCheckpoint */) public {
507507
// TODO: check for 2/3+1 sig and validate non-inclusion in newStateUpdate
508508
// UPDATE: since we've moved rewards to on chain there is no urgent need for this function
509-
// becuase heimdall fee can be trusted on 2/3+1 security
509+
// becuase heimdall fee can be trusted on 2/3+1 security
510510
}
511511

512512
function _stakeFor(address user, uint256 amount, address signer, bool isContract) internal {

deploy-migrations/2_deploy_root_contracts.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,15 @@ module.exports = async function (deployer) {
146146
RootChain.address
147147
)
148148

149+
await deployer.deploy(ExitNFT, Registry.address)
149150
await deployer.deploy(WithdrawManager)
150151
await deployer.deploy(
151152
WithdrawManagerProxy,
152153
WithdrawManager.address,
153154
Registry.address,
154-
RootChain.address
155+
RootChain.address,
156+
ExitNFT.address
155157
)
156-
await deployer.deploy(ExitNFT, Registry.address)
157158

158159
console.log('deploying predicates...')
159160
await deployer.deploy(

deploy-migrations/3_initialize_state.js

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ const ERC20Predicate = artifacts.require('ERC20Predicate')
1313
const ERC721Predicate = artifacts.require('ERC721Predicate')
1414
const MarketplacePredicate = artifacts.require('MarketplacePredicate')
1515
const TransferWithSigPredicate = artifacts.require('TransferWithSigPredicate')
16-
const ExitNFT = artifacts.require('ExitNFT')
1716
const MaticWeth = artifacts.require('MaticWETH')
1817
const TestToken = artifacts.require('TestToken')
1918

@@ -24,13 +23,11 @@ module.exports = async function (deployer, network) {
2423
.all([
2524
TestToken.deployed(),
2625
Registry.deployed(),
27-
RootChain.deployed(),
2826
DepositManagerProxy.deployed(),
2927
StateSender.deployed(),
3028
WithdrawManagerProxy.deployed(),
3129
StakeManager.deployed(),
3230
SlashingManager.deployed(),
33-
ExitNFT.deployed(),
3431
MaticWeth.deployed(),
3532
ERC20Predicate.deployed(),
3633
ERC721Predicate.deployed(),
@@ -40,23 +37,17 @@ module.exports = async function (deployer, network) {
4037
.spread(async function (
4138
testToken,
4239
registry,
43-
rootChain,
4440
depositManagerProxy,
4541
stateSender,
4642
withdrawManagerProxy,
4743
stakeManager,
4844
slashingManager,
49-
exitNFT,
5045
maticWeth,
5146
ERC20Predicate,
5247
ERC721Predicate,
5348
MarketplacePredicate,
5449
TransferWithSigPredicate
5550
) {
56-
const _withdrawManager = await WithdrawManager.at(
57-
withdrawManagerProxy.address
58-
)
59-
await _withdrawManager.setExitNFTContract(exitNFT.address)
6051
await registry.updateContractMap(
6152
ethUtils.keccak256('depositManager'),
6253
depositManagerProxy.address

moonwalker-migrations/queueJobs.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ async function deploy() {
4141
await deployer.deploy(transformArtifact('DepositManagerProxy', ['DepositManager', 'Registry', 'RootChain']))
4242

4343
await deployer.deploy(transformArtifact('WithdrawManager', []))
44-
await deployer.deploy(transformArtifact('WithdrawManagerProxy', ['WithdrawManager', 'Registry', 'RootChain']))
44+
await deployer.deploy(transformArtifact('ExitNFT', ['Registry']))
45+
await deployer.deploy(transformArtifact('WithdrawManagerProxy', ['WithdrawManager', 'Registry', 'RootChain', 'ExitNFT']))
4546

4647
await deployer.deploy(transformArtifact('TestToken', [{ value: 'Test Token' }, { value: 'TST' }]))
4748

test/helpers/deployer.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,17 +152,14 @@ class Deployer {
152152
this.withdrawManagerProxy = await contracts.WithdrawManagerProxy.new(
153153
this.withdrawManager.address,
154154
this.registry.address,
155-
this.rootChain.address
155+
this.rootChain.address,
156+
this.exitNFT.address
156157
)
157158
await this.registry.updateContractMap(
158159
ethUtils.keccak256('withdrawManager'),
159160
this.withdrawManagerProxy.address
160161
)
161-
const w = await contracts.WithdrawManager.at(
162-
this.withdrawManagerProxy.address
163-
)
164-
await w.setExitNFTContract(this.exitNFT.address)
165-
return w
162+
return contracts.WithdrawManager.at(this.withdrawManagerProxy.address)
166163
}
167164

168165
async deployErc20Predicate() {

0 commit comments

Comments
 (0)