Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #909 proxy delegatecall #1152

Merged
merged 46 commits into from
Oct 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
81ab74f
Validates in Proxy.sol if address is a contract,implements #909
Sep 12, 2019
05a79bb
adapting to the same code format
Sep 15, 2019
600647c
adding Warning to avoid using the isContract function from a constructor
Sep 15, 2019
25d36c4
Merge pull request #1 from celo-org/master
r00ted199 Sep 15, 2019
333c102
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 15, 2019
0cb2519
adding timeout
Sep 16, 2019
db37486
applying address contract check to fallback function
Sep 17, 2019
23f512b
commenting circleci protocol timeout
Sep 17, 2019
4863833
linting and small changes to improve the code reading
Sep 17, 2019
3f34dd6
Merge pull request #2 from celo-org/master
r00ted199 Sep 19, 2019
2568f85
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 19, 2019
b1fdbd0
fixing e2e transfer test with new gas estimates
Sep 19, 2019
eb3f125
adding details about how to execute this e2e test in local
Sep 19, 2019
8089220
fixing accounts doc issue
Sep 19, 2019
78f627a
moving isContract check to _setImplementation
Sep 19, 2019
7bf1b03
Merge pull request #3 from celo-org/master
r00ted199 Sep 20, 2019
fdde8ba
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 20, 2019
4d26ae3
adds the validation of is a contract address before executing call or…
Sep 20, 2019
44d8570
style nits
Sep 21, 2019
2038095
Merge branch 'master' into feature/909-proxy-delegatecall
r00ted199 Sep 21, 2019
a65fed6
Merge branch 'master' into feature/909-proxy-delegatecall
r00ted199 Sep 23, 2019
2a6052a
Merge pull request #4 from celo-org/master
r00ted199 Sep 24, 2019
96945ed
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 24, 2019
9d53836
fixing conflict and doing check if dataLength > 0
Sep 24, 2019
45c2a9a
Merge branch 'feature/909-proxy-delegatecall' of https://github.com/r…
Sep 24, 2019
58bc4ae
fixing conflict
Sep 24, 2019
ab8d380
Merge pull request #5 from celo-org/master
r00ted199 Sep 24, 2019
def8fdd
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 24, 2019
f7d98bf
simple text replacement
Sep 25, 2019
24de378
Merge branch 'feature/909-proxy-delegatecall' of https://github.com/r…
Sep 25, 2019
3809b07
Merge branch 'master' into feature/909-proxy-delegatecall
m-chrzan Sep 26, 2019
e974897
Merge branch 'master' into feature/909-proxy-delegatecall
timmoreton Sep 28, 2019
755026a
Merge branch 'master' into feature/909-proxy-delegatecall
m-chrzan Sep 30, 2019
f5f63bb
Merge branch 'master' into feature/909-proxy-delegatecall
Sep 30, 2019
f32d0dd
Merge pull request #6 from celo-org/master
r00ted199 Oct 1, 2019
b5b7128
Merge branch 'master' into feature/909-proxy-delegatecall
Oct 1, 2019
c4ff753
Merge branch 'feature/909-proxy-delegatecall' of https://github.com/r…
Oct 1, 2019
a02c50e
Merge pull request #7 from celo-org/master
r00ted199 Oct 3, 2019
ff488b1
Merge branch 'master' into feature/909-proxy-delegatecall
Oct 3, 2019
7a7adf0
Merge pull request #8 from celo-org/master
r00ted199 Oct 7, 2019
02cdbaf
Merge branch 'master' into feature/909-proxy-delegatecall
Oct 7, 2019
c736be3
Merge pull request #9 from celo-org/master
r00ted199 Oct 7, 2019
6076dfb
Merge branch 'master' into feature/909-proxy-delegatecall
Oct 7, 2019
22d24a6
Merge pull request #10 from celo-org/master
r00ted199 Oct 7, 2019
b7cd678
Merge branch 'master' into feature/909-proxy-delegatecall
Oct 7, 2019
b9ec124
line
Oct 7, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/protocol/contracts/common/MultiSig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pragma solidity ^0.5.3;
/* solhint-disable no-inline-assembly, avoid-low-level-calls, func-name-mixedcase, func-order */

import "./Initializable.sol";
import "./libraries/AddressesHelper.sol";


/// @title Multisignature wallet - Allows multiple parties to agree on transactions before
Expand Down Expand Up @@ -261,6 +262,10 @@ contract MultiSig is Initializable {
returns (bool)
{
bool result;

if (dataLength > 0)
require(AddressesHelper.isContract(destination), "Invalid contract address");

/* solhint-disable max-line-length */
assembly {
let x := mload(0x40) // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
Expand Down
12 changes: 11 additions & 1 deletion packages/protocol/contracts/common/Proxy.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pragma solidity ^0.5.3;
/* solhint-disable no-inline-assembly, no-complex-fallback, avoid-low-level-calls */

import "./libraries/AddressesHelper.sol";

/**
* @title A Proxy utilizing the Unstructured Storage pattern.
Expand Down Expand Up @@ -32,8 +33,15 @@ contract Proxy {
function () external payable {
bytes32 implementationPosition = IMPLEMENTATION_POSITION;

address implementationAddress;

assembly {
implementationAddress := sload(implementationPosition)
}

require(AddressesHelper.isContract(implementationAddress), "Invalid contract address");

assembly {
let implementationAddress := sload(implementationPosition)
let newCallDataPosition := mload(0x40)
mstore(0x40, add(newCallDataPosition, calldatasize))

Expand Down Expand Up @@ -114,6 +122,8 @@ contract Proxy {
function _setImplementation(address implementation) public onlyOwner {
bytes32 implementationPosition = IMPLEMENTATION_POSITION;

require(AddressesHelper.isContract(implementation), "Invalid contract address");

assembly {
sstore(implementationPosition, implementation)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
pragma solidity ^0.5.3;

/**
* @title Library with support functions to deal with addresses
*/
library AddressesHelper {

/**
* @dev isContract detect whether the address is
* a contract address or externally owned account (EOA)
* WARNING: Calling this function from a constructor will return false
* independently if the address given as parameter is a contract or EOA
* @return true if it is a contract address
*/
function isContract(address addr) internal view returns (bool) {
uint256 size;
/* solium-disable-next-line security/no-inline-assembly */
assembly { size := extcodesize(addr) }
return size > 0;
}
}
5 changes: 5 additions & 0 deletions packages/protocol/contracts/governance/Proposals.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "solidity-bytes-utils/contracts/BytesLib.sol";

import "../common/FixidityLib.sol";
import "../common/libraries/AddressesHelper.sol";

/**
* @title A library operating on Celo Governance proposals.
Expand Down Expand Up @@ -324,6 +325,10 @@ library Proposals {
returns (bool)
{
bool result;

if (dataLength > 0)
require(AddressesHelper.isContract(destination), "Invalid contract address");

/* solhint-disable no-inline-assembly */
assembly {
/* solhint-disable max-line-length */
Expand Down
7 changes: 7 additions & 0 deletions packages/protocol/test/common/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ contract('Proxy', (accounts: string[]) => {
assert.equal(events[0].event, 'ImplementationSet')
})

it('should not allow to call a non contract address', async () =>
assertRevert(
proxy._setAndInitializeImplementation(accounts[1], initializeData(42), {
from: accounts[1],
})
))

it('should not allow a non-owner to set an implementation', async () =>
assertRevert(
proxy._setAndInitializeImplementation(hasInitializer.address, initializeData(42), {
Expand Down
23 changes: 23 additions & 0 deletions packages/protocol/test/governance/governance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,29 @@ contract('Governance', (accounts: string[]) => {
await assertRevert(governance.execute(proposalId, index))
})
})

describe('when the proposal cannot execute because it is not a contract address', () => {
beforeEach(async () => {
await governance.propose(
[transactionSuccess1.value],
[accounts[1]],
transactionSuccess1.data,
[transactionSuccess1.data.length],
// @ts-ignore: TODO(mcortesi) fix typings for TransactionDetails
{ value: minDeposit }
)
await timeTravel(dequeueFrequency, web3)
await governance.approve(proposalId, index)
await timeTravel(approvalStageDuration, web3)
await mockLockedGold.setWeight(account, weight)
await governance.vote(proposalId, index, value)
await timeTravel(referendumStageDuration, web3)
})

it('should revert', async () => {
await assertRevert(governance.execute(proposalId, index))
})
})
})

describe('when executing a proposal with two transactions', () => {
Expand Down