Skip to content

Commit

Permalink
polish DSWv7 and add initial ERC1271 coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Feb 10, 2020
1 parent f945a16 commit 9343296
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 39 deletions.
1 change: 1 addition & 0 deletions contracts/helpers/SmartWalletRevertReasonHelperV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ contract SmartWalletRevertReasonHelperV1 {
if (code == 27) return "Invalid `to` parameter - cannot supply the address of this contract.";
if (code == 28) return "Invalid `to` parameter - cannot supply the Dharma Escape Hatch Registry.";
if (code == 29) return "Invalid custom action type.";
if (code == 30) return "Insufficient data supplied.";
return "(no revert reason)";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ contract DharmaSmartWalletImplementationV7 is
);

SmartWalletRevertReasonHelperV1 internal constant _REVERT_REASON_HELPER = (
SmartWalletRevertReasonHelperV1(0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d)
SmartWalletRevertReasonHelperV1(0xE24257338d0c15f3Dd00Ed59fcA9e50CfB167bA8)
);

// Compound returns a value of 0 to indicate success, or lack of an error.
Expand Down Expand Up @@ -1107,7 +1107,10 @@ contract DharmaSmartWalletImplementationV7 is
* supplied data. The data must be ABI encoded as (bytes32, bytes), where the
* first bytes32 parameter represents the hash digest for validating the
* supplied signatures and the second bytes parameter contains context for the
* requested validation.
* requested validation. The two signatures are packed together, with the one
* from Dharma coming first and that from the user coming second - this is so
* that, in future versions, multiple user signatures may be supplied if the
* associated key ring requires them.
* @param data bytes The data used to validate the signature.
* @param signatures bytes The two signatures, each 65 bytes - one from the
* owner (using ERC-1271 as well if the user signing key is a contract) and
Expand All @@ -1121,13 +1124,15 @@ contract DharmaSmartWalletImplementationV7 is
// Get message hash digest and any additional context from data argument.
bytes32 digest;
bytes memory context;

if (data.length == 32) {
digest = abi.decode(data, (bytes32));
} else {
require(data.length >= 64, _revertReason(30));
(digest, context) = abi.decode(data, (bytes32, bytes));
}

// Get user signature & Dharma signature from combined signatures argument.
// Get Dharma signature & user signature from combined signatures argument.
require(signatures.length == 130, _revertReason(11));
bytes memory signaturesInMemory = signatures;
bytes32 r;
Expand All @@ -1138,14 +1143,14 @@ contract DharmaSmartWalletImplementationV7 is
s := mload(add(signaturesInMemory, 0x40))
v := byte(0, mload(add(signaturesInMemory, 0x60)))
}
bytes memory userSignature = abi.encodePacked(r, s, v);
bytes memory dharmaSignature = abi.encodePacked(r, s, v);

assembly {
r := mload(add(signaturesInMemory, 0x61))
s := mload(add(signaturesInMemory, 0x81))
v := byte(0, mload(add(signaturesInMemory, 0xa1)))
}
bytes memory dharmaSignature = abi.encodePacked(r, s, v);
bytes memory userSignature = abi.encodePacked(r, s, v);

// Validate user signature with `SignatureVerification` as the action type.
require(
Expand Down Expand Up @@ -2199,7 +2204,7 @@ contract DharmaSmartWalletImplementationV7 is
revertReason = abi.decode(revertReasonBytes, (string));
} else {
// Simply return the default, with no revert reason.
revertReason = _revertReason(30);
revertReason = _revertReason(uint256(-1));
}
}

Expand Down
6 changes: 4 additions & 2 deletions scripts/test/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ module.exports = Object.freeze({
CDAI_MAINNET_ADDRESS: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
CUSDC_MAINNET_ADDRESS: "0x39AA39c021dfbaE8faC545936693aC917d5E7563",
CETH_MAINNET_ADDRESS: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5",
DDAI_MAINNET_ADDRESS: "0x00000000001876eB1444c986fD502e618c587430",
DUSDC_MAINNET_ADDRESS: "0x00000000008943c65cAf789FFFCF953bE156f6f8",
DAI_MIGRATOR_MAINNET_ADDRESS: "0xc73e0383F3Aff3215E6f04B0331D58CeCf0Ab849",
MOCK_USDC_BLACKLISTED_ADDRESS: "0x6000000000000000000000000000000000000006",
COMPTROLLER_MAINNET_ADDRESS: "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B",
Expand Down Expand Up @@ -262,7 +264,7 @@ module.exports = Object.freeze({
"20204b657952696e6755706772616465426561636f6e50726f78795631202020"
],
REVERT_REASON_HELPER_METADATA: [
"373389197482e319656922b5cf379766d403a45bdb1776717726e0d125834166"
"cc6f0e10e5acac6b087faf256f191349c398a4fc1e1ca52f2372ad1ecffc2704"
],
KEY_RING_FACTORY_V2_ADDRESS: "0x2484000059004afB720000dc738434fA6200F49D",
KEY_RING_FACTORY_V2_SALT:
Expand Down Expand Up @@ -317,7 +319,7 @@ module.exports = Object.freeze({
"0x0000000000f55ff05D0080fE17A63b16596Fd59f",
INDESTRUCTIBLE_REGISTRY_RUNTIME_HASH:
"0xadca137a47625f8ad1da20be107380101474374dc6c31ad0b8c1807558ea3c29",
REVERT_REASON_HELPER_ADDRESS: "0x13821c0129FB9e2CC16dE2660783Ff4E4861e92d",
REVERT_REASON_HELPER_ADDRESS: "0xE24257338d0c15f3Dd00Ed59fcA9e50CfB167bA8",
INDESTRUCTIBLE_REGISTRY_CREATION_TX:
"0x64e030870000000000000000000000000000000000000000a4ab82b860e6cb06780400" +
"000000000000000000000000000000000000000000000000000000000000000040000000" +
Expand Down
24 changes: 12 additions & 12 deletions scripts/test/deploy.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,18 @@ async function test(testingContext) {
}

/*
console.log(
swapMetadataHash(
DharmaSmartWalletImplementationV7Artifact.bytecode,
constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA
),
web3.utils.keccak256(swapMetadataHash(
DharmaSmartWalletImplementationV7Artifact.bytecode,
constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA
), {encoding: 'hex'})
)
process.exit(0)
*/
console.log(
swapMetadataHash(
DharmaSmartWalletImplementationV7Artifact.bytecode,
constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA
),
web3.utils.keccak256(swapMetadataHash(
DharmaSmartWalletImplementationV7Artifact.bytecode,
constants.DHARMA_SMART_WALLET_IMPLEMENTATION_V7_METADATA
), {encoding: 'hex'})
)
process.exit(0)
*/

const DharmaUpgradeBeaconController = new web3.eth.Contract(
DharmaUpgradeBeaconControllerArtifact.abi,
Expand Down
94 changes: 75 additions & 19 deletions scripts/test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4461,25 +4461,6 @@ async function test(testingContext) {
tester.originalAddress
);

/* TODO: get this working manually
const withdrawalMessage = (
UserSmartWallet.options.address + // smart wallet address
constants.NULL_BYTES_32.slice(2) + // smart wallet version
address.slice(2) + // user dharma key
address.slice(2) + // dharma key registry key
'5'.padStart(64, '0') + // nonce
constants.NULL_BYTES_32.slice(2) + // minimum gas
'04' + // action type
'f'.padStart(64, 'f') + // amount
address.slice(2) // recipient
)
const saiWithdrawalSignature = tester.signHashedPrefixedHashedHexString(
withdrawalMessage,
address
)
*/

await tester.runTest(
"V7 UserSmartWallet can get a Dai withdrawal custom action ID",
UserSmartWalletV7,
Expand Down Expand Up @@ -6629,6 +6610,81 @@ async function test(testingContext) {
tester.originalAddress
);

await tester.runTest(
`Check allowance is not set before meta-tx`,
tester.DUSDC,
"allowance",
"call",
[UserSmartWalletV7.options.address, tester.addressTwo],
true,
value => {
assert.strictEqual(value, '0');
}
);

let messageHash;
await tester.runTest(
`Get message hash for meta-transaction approval`,
tester.DUSDC_META,
"getMetaTransactionMessageHash",
"call",
[
"0x2d657fa5", // `modifyAllowanceViaMetaTransaction`
web3.eth.abi.encodeParameters(
["address", "address", "uint256", "bool"],
[UserSmartWalletV7.options.address, tester.addressTwo, '1', true]
),
0, // No expiration
constants.NULL_BYTES_32 // no salt
],
true,
values => {
assert.ok(values.valid);
messageHash = values.messageHash;
}
);

const messageHashSignature = tester.signHashedPrefixedHexString(
messageHash,
tester.address
);

const messageHashUserSignature = tester.signHashedPrefixedHexString(
messageHash,
tester.addressTwo
);

await tester.runTest(
`dUSDC allowance is modifiable via meta-transaction`,
tester.DUSDC_META,
"modifyAllowanceViaMetaTransaction",
"send",
[
UserSmartWalletV7.options.address,
tester.addressTwo,
'1',
true,
0,
constants.NULL_BYTES_32,
messageHashSignature + messageHashUserSignature.slice(2)
],
true,
receipt => {
// TODO: validate
}
);

await tester.runTest(
`Check allowance is set after meta-tx`,
tester.DUSDC,
"allowance",
"call",
[UserSmartWalletV7.options.address, tester.addressTwo],
true,
value => {
assert.strictEqual(value, '1');
}
);

// Initiate account recovery
await tester.runTest(
Expand Down
21 changes: 21 additions & 0 deletions scripts/test/testHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -1148,6 +1148,27 @@ class Tester {
IERC20Artifact.abi, constants.CUSDC_MAINNET_ADDRESS
);

this.DDAI = new web3.eth.Contract(
IERC20Artifact.abi, constants.DDAI_MAINNET_ADDRESS
);

this.DUSDC = new web3.eth.Contract(
IERC20Artifact.abi, constants.DUSDC_MAINNET_ADDRESS
);

const MetaABI = [
{"constant":false,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bool","name":"increase","type":"bool"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"bytes","name":"signatures","type":"bytes"}],"name":"modifyAllowanceViaMetaTransaction","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},
{"constant":true,"inputs":[{"internalType":"bytes4","name":"functionSelector","type":"bytes4"},{"internalType":"bytes","name":"arguments","type":"bytes"},{"internalType":"uint256","name":"expiration","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"getMetaTransactionMessageHash","outputs":[{"internalType":"bytes32","name":"messageHash","type":"bytes32"},{"internalType":"bool","name":"valid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"}
]

this.DDAI_META = new web3.eth.Contract(
MetaABI, constants.DDAI_MAINNET_ADDRESS
);

this.DUSDC_META = new web3.eth.Contract(
MetaABI, constants.DUSDC_MAINNET_ADDRESS
);

this.BadBeaconDeployer = this.newDeployer(BadBeaconArtifact);

this.BadBeaconTwoDeployer = this.newDeployer(BadBeaconTwoArtifact);
Expand Down

0 comments on commit 9343296

Please sign in to comment.