@0x:contracts-staking
Added tests for simpleProxyCallWithData()
This commit is contained in:
parent
2ed63970d4
commit
1fc57baac1
@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
import "@0x/contracts-utils/contracts/src/Ownable.sol";
|
||||
import "./libs/LibProxy.sol";
|
||||
@ -72,6 +73,30 @@ contract StakingProxy is
|
||||
_attachStakingContract(_stakingContract);
|
||||
}
|
||||
|
||||
/// @dev Detach the current staking contract.
|
||||
/// Note that this is callable only by this contract's owner.
|
||||
function detachStakingContract()
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
stakingContract = NIL_ADDRESS;
|
||||
emit StakingContractDetachedFromProxy();
|
||||
}
|
||||
|
||||
/// @dev Set read-only mode (state cannot be changed).
|
||||
function setReadOnlyMode(bool readOnlyMode)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
if (readOnlyMode) {
|
||||
stakingContract = readOnlyProxy;
|
||||
} else {
|
||||
stakingContract = readOnlyProxyCallee;
|
||||
}
|
||||
|
||||
emit ReadOnlyModeSet(readOnlyMode);
|
||||
}
|
||||
|
||||
/// @dev Batch executes a series of calls to the exchange contract.
|
||||
/// @param data An array of data that encodes a sequence of functions to
|
||||
/// call in the staking contracts.
|
||||
@ -99,31 +124,7 @@ contract StakingProxy is
|
||||
batchReturnData[i] = returnData;
|
||||
}
|
||||
|
||||
return batchReturnData
|
||||
}
|
||||
|
||||
/// @dev Detach the current staking contract.
|
||||
/// Note that this is callable only by this contract's owner.
|
||||
function detachStakingContract()
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
stakingContract = NIL_ADDRESS;
|
||||
emit StakingContractDetachedFromProxy();
|
||||
}
|
||||
|
||||
/// @dev Set read-only mode (state cannot be changed).
|
||||
function setReadOnlyMode(bool readOnlyMode)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
if (readOnlyMode) {
|
||||
stakingContract = readOnlyProxy;
|
||||
} else {
|
||||
stakingContract = readOnlyProxyCallee;
|
||||
}
|
||||
|
||||
emit ReadOnlyModeSet(readOnlyMode);
|
||||
return batchReturnData;
|
||||
}
|
||||
|
||||
/// @dev Attach a staking contract; future calls will be delegated to the staking contract.
|
||||
|
@ -122,7 +122,7 @@ library LibProxy {
|
||||
{
|
||||
if (destination == address(0)) {
|
||||
LibRichErrors.rrevert(
|
||||
LibStakingRichErrors.ProxyDestinationCannotBeNil()
|
||||
LibStakingRichErrors.ProxyDestinationCannotBeNilError()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,4 +71,14 @@ contract TestLibProxy {
|
||||
proxyCallArgs = args;
|
||||
(success, returnData) = address(this).call(data);
|
||||
}
|
||||
|
||||
/// @dev Calls the destination with the provided calldata.
|
||||
/// @param destination The contract that should be called by the proxy call.
|
||||
/// @param data The bytes that should be used to call into the destination contract.
|
||||
function publicSimpleProxyCallWithData(address destination, bytes memory data)
|
||||
public
|
||||
returns (bool success, bytes memory returnData)
|
||||
{
|
||||
return destination.simpleProxyCallWithData(data);
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import { StakingRevertErrors } from '@0x/order-utils';
|
||||
|
||||
import { artifacts, TestLibProxyContract, TestLibProxyReceiverContract } from '../../src';
|
||||
|
||||
blockchainTests.resets.only('LibProxy', env => {
|
||||
blockchainTests.resets('LibProxy', env => {
|
||||
let proxy: TestLibProxyContract;
|
||||
let receiver: TestLibProxyReceiverContract;
|
||||
|
||||
@ -37,6 +37,14 @@ blockchainTests.resets.only('LibProxy', env => {
|
||||
NeverRevert,
|
||||
}
|
||||
|
||||
interface PublicProxyCallArgs {
|
||||
destination: string;
|
||||
revertRule: RevertRule;
|
||||
customEgressSelector: string;
|
||||
ignoreIngressSelector: boolean;
|
||||
calldata: string;
|
||||
}
|
||||
|
||||
// Choose a random 4 byte string of calldata to send and prepend with `0x00` to ensure
|
||||
// that it does not call `externalProxyCall` by accident. This calldata will make the fallback
|
||||
// in `TestLibProxyReceiver` fail because it is 4 bytes long.
|
||||
@ -51,14 +59,6 @@ blockchainTests.resets.only('LibProxy', env => {
|
||||
return hexConcat('0x00', hexRandom(35));
|
||||
}
|
||||
|
||||
interface PublicProxyCallArgs {
|
||||
destination: string;
|
||||
revertRule: RevertRule;
|
||||
customEgressSelector: string;
|
||||
ignoreIngressSelector: boolean;
|
||||
calldata: string;
|
||||
}
|
||||
|
||||
// Exposes `publicProxyCall()` with useful default arguments.
|
||||
async function publicProxyCallAsync(args: Partial<PublicProxyCallArgs>): Promise<[boolean, string]> {
|
||||
return proxy.publicProxyCall.callAsync(
|
||||
@ -72,27 +72,27 @@ blockchainTests.resets.only('LibProxy', env => {
|
||||
);
|
||||
}
|
||||
|
||||
// Verifies that the result of a given call to `proxyCall()` results in specified outcome
|
||||
function verifyPostConditions(result: [boolean, string], success: boolean, calldata: string): void {
|
||||
expect(result[0]).to.be.eq(success);
|
||||
expect(result[1]).to.be.eq(calldata);
|
||||
}
|
||||
|
||||
// Verifies that the result of a given call to `proxyCall()` results in `ProxyDestinationCannotBeNilError`
|
||||
function verifyDestinationZeroError(result: [boolean, string]): void {
|
||||
const expectedError = new StakingRevertErrors.ProxyDestinationCannotBeNilError();
|
||||
expect(result[0]).to.be.false();
|
||||
expect(result[1]).to.be.eq(expectedError.encode());
|
||||
}
|
||||
|
||||
describe('proxyCall', () => {
|
||||
// Verifies that the result of a given call to `proxyCall()` results in specified outcome
|
||||
function verifyPostConditions(result: [boolean, string], success: boolean, calldata: string): void {
|
||||
expect(result[0]).to.be.eq(success);
|
||||
expect(result[1]).to.be.eq(calldata);
|
||||
}
|
||||
|
||||
describe('Failure Conditions', () => {
|
||||
// Verifies that the result of a given call to `proxyCall()` results in `ProxyDestinationCannotBeNilError`
|
||||
function checkDestinationZeroError(result: [boolean, string]): void {
|
||||
const expectedError = new StakingRevertErrors.ProxyDestinationCannotBeNilError();
|
||||
expect(result[0]).to.be.false();
|
||||
expect(result[1]).to.be.eq(expectedError.encode());
|
||||
}
|
||||
|
||||
it('should revert when the destination is address zero', async () => {
|
||||
checkDestinationZeroError(await publicProxyCallAsync({ destination: constants.NULL_ADDRESS }));
|
||||
verifyDestinationZeroError(await publicProxyCallAsync({ destination: constants.NULL_ADDRESS }));
|
||||
});
|
||||
|
||||
it('should revert when the destination is address zero and revertRule == AlwaysRevert', async () => {
|
||||
checkDestinationZeroError(
|
||||
verifyDestinationZeroError(
|
||||
await publicProxyCallAsync({
|
||||
destination: constants.NULL_ADDRESS,
|
||||
revertRule: RevertRule.AlwaysRevert,
|
||||
@ -101,7 +101,7 @@ blockchainTests.resets.only('LibProxy', env => {
|
||||
});
|
||||
|
||||
it('should revert when the destination is address zero and revertRule == NeverRevert', async () => {
|
||||
checkDestinationZeroError(
|
||||
verifyDestinationZeroError(
|
||||
await publicProxyCallAsync({
|
||||
destination: constants.NULL_ADDRESS,
|
||||
revertRule: RevertRule.NeverRevert,
|
||||
@ -271,4 +271,33 @@ blockchainTests.resets.only('LibProxy', env => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('simpleProxyCallWithData', () => {
|
||||
it('should revert if address zero is the destination', async () => {
|
||||
const expectedError = new StakingRevertErrors.ProxyDestinationCannotBeNilError();
|
||||
const tx = proxy.publicSimpleProxyCallWithData.awaitTransactionSuccessAsync(
|
||||
constants.NULL_ADDRESS,
|
||||
constants.NULL_BYTES,
|
||||
);
|
||||
return expect(tx).to.revertWith(expectedError);
|
||||
});
|
||||
|
||||
it('should call the receiver with the correct calldata and report a success when the receiver succeeds', async () => {
|
||||
const calldata = constructRandomSuccessCalldata();
|
||||
verifyPostConditions(
|
||||
await proxy.publicSimpleProxyCallWithData.callAsync(receiver.address, calldata),
|
||||
true,
|
||||
calldata,
|
||||
);
|
||||
});
|
||||
|
||||
it('should call the receiver with the correct calldata and report a success when the receiver succeeds', async () => {
|
||||
const calldata = constructRandomFailureCalldata();
|
||||
verifyPostConditions(
|
||||
await proxy.publicSimpleProxyCallWithData.callAsync(receiver.address, calldata),
|
||||
false,
|
||||
calldata,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user