Skip to content
This repository has been archived by the owner on Mar 16, 2023. It is now read-only.

Commit

Permalink
feat(sdk): sorking permit signature for dai
Browse files Browse the repository at this point in the history
  • Loading branch information
joeandrews committed Feb 25, 2020
1 parent 29aa927 commit 7741b90
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const backgroundContracts = [
'AccountRegistry',
'ZkAsset',
'ERC20',
'IERC20Permit',
];

export default async function setupNetworkConfig({
Expand Down
56 changes: 28 additions & 28 deletions packages/extension/src/client/services/MetaMaskService/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ const handleAction = async (action, params) => {
const sigParams = ethUtil.fromRpcSig(signature);
const publicKey = ethUtil.ecrecover(hash, sigParams.v, sigParams.r, sigParams.s);


response = {
signature: result,
publicKey,
Expand Down Expand Up @@ -102,38 +101,39 @@ const handleAction = async (action, params) => {

break;
}
case 'metamask.eip712.permit': {
const {
allowed,
exipiry,
nonce,
spender,
verifyingContract,
} = params;
case 'metamask.eip712.permit': {
const {
allowed,
expiry,
nonce,
spender,
verifyingContract,
} = params;

const permitSchema = permit({
allowed,
exipiry,
nonce,
spender,
verifyingContract
});
const method = 'eth_signTypedData_v4';
const { result } = await Web3Service.sendAsync({
method,
params: [address, permitSchema],
from: address,
});
const permit = permitSchema({
allowed,
expiry,
nonce,
spender,
holder: address,
verifyingContract,
chainId: Web3Service.networkId,
});
const method = 'eth_signTypedData_v4';
const { result } = await Web3Service.sendAsync({
method,
params: [address, permit],
from: address,
});

response = {
signature: result,
};
response = {
signature: result,
};

break;
}
default:
break;
}
default:
break;
}

return response;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@ const {
},
} = utils;


export default ({
spender,
verifyingContract,
allowed,
expiry,
spender,
nonce
nonce,
chainId,
holder,
}) => {
const domain = signer.generateDAIDomainparams(chainId, verifyingContract);
const domain = signer.generateDAIDomainParams(chainId, verifyingContract);
const schema = eip712.PERMIT_SIGNATURE;

const message = {
allowed,
spender,
holder,
expiry,
nonce,
};
Expand Down
3 changes: 3 additions & 0 deletions packages/extension/src/config/contracts/contracts.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ export default {
ERC20: {
name: 'ERC20',
},
IERC20Permit: {
name: 'IERC20Permit',
},
};
2 changes: 2 additions & 0 deletions packages/extension/src/config/contracts/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import AccountRegistry from '~contracts/IAccountRegistryBehaviour.json';
import AccountRegistryManager from '~contracts/IAccountRegistryManager.json';
import ACE from '~contracts/ACE.json';
import IERC20 from '~contracts/IERC20Mintable.json';
import IERC20Permit from '~contracts/IERC20Permit.json';
import IZkAsset from '~contracts/IZkAsset.json';

export default {
Expand All @@ -10,4 +11,5 @@ export default {
ACE,
ZkAsset: IZkAsset,
ERC20: IERC20,
IERC20Permit,
};
2 changes: 2 additions & 0 deletions packages/extension/src/config/contracts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const {
ACE,
ZkAsset,
ERC20,
IERC20Permit,
} = configs;

export {
Expand All @@ -28,4 +29,5 @@ export {
ACE,
ZkAsset,
ERC20,
IERC20Permit,
};
2 changes: 2 additions & 0 deletions packages/extension/src/config/contracts/production.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import AccountRegistry from '~contracts/IAccountRegistryBehaviour.json';
import AccountRegistryManager from '~contracts/IAccountRegistryManager.json';
import ACE from '~contracts/IACE.json';
import IERC20 from '~contracts/IERC20Mintable.json';
import IERC20Permit from '~contracts/IERC20Permit.json';
import IZkAsset from '~contracts/IZkAsset.json';

export default {
Expand All @@ -10,4 +11,5 @@ export default {
ACE,
ZkAsset: IZkAsset,
ERC20: IERC20,
IERC20Permit,
};
2 changes: 1 addition & 1 deletion packages/extension/src/config/supportsPermitSignature.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export default {
'0x6b175474e89094c44da98b954eedeac495271d0f': true,
'0x6B175474E89094C44Da98b954EedeAC495271d0F': true,
};
44 changes: 44 additions & 0 deletions packages/extension/src/ui/apis/asset/depositWithPermit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import ConnectionService from '~/ui/services/ConnectionService';

export default async function deposit({
currentAccount: {
address: currentAddress,
},
erc20Amount,
assetAddress,
proof,
isGSNAvailable,
signature,
expiry,
nonce,
}) {
const proofHash = proof.hash;
const proofData = proof.encodeABI(assetAddress);

const transactionData = {
contract: 'AccountRegistry',
method: 'deposit',
data: [
assetAddress,
currentAddress,
proofHash,
proofData,
erc20Amount.toString(),
signature,
nonce,
expiry,
],
};

const response = isGSNAvailable
? await ConnectionService.sendTransaction(transactionData)
: await ConnectionService.post({
action: 'metamask.send',
data: transactionData,
});

return {
...response,
success: !!(response && response.txReceipt),
};
}
4 changes: 4 additions & 0 deletions packages/extension/src/ui/apis/asset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import getAssets from './getAssets';
import getDomainAssets from './getDomainAssets';
import getLinkedTokenAddress from './getLinkedTokenAddress';
import approveERC20Allowance from './approveERC20Allowance';
import permitERC20Allowance from './permitERC20Allowance';
import confidentialTransferFrom from './confidentialTransferFrom';
import confidentialTransfer from './confidentialTransfer';
import updateNoteMetadata from './updateNoteMetadata';
import deposit from './deposit';
import depositWithPermit from './depositWithPermit';

export const getPastTransactions = () => [];

Expand All @@ -16,8 +18,10 @@ export {
getDomainAssets,
getLinkedTokenAddress,
approveERC20Allowance,
permitERC20Allowance,
confidentialTransferFrom,
confidentialTransfer,
updateNoteMetadata,
deposit,
depositWithPermit
};
26 changes: 13 additions & 13 deletions packages/extension/src/ui/apis/asset/permitERC20Allowance.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,52 @@ import Web3Service from '~/helpers/Web3Service';

export default async function permitERC20({
asset,
requestedAllowance,
allowanceSpender,
}) {


const {
linkedTokenAddress,
} = asset;

let error;
let nonce;
try {
const nonce = await Web3Service
.useContract('ERC20')
nonce = await Web3Service
.useContract('IERC20Permit')
.at(linkedTokenAddress)
.method('nonces')
.send(
.call(
allowanceSpender,
);
} catch (e) {
console.log(e);
error = e;
}
const exipry = Date.now() + 24 * 60 * 60;
const expiry = Date.now() + 24 * 60 * 60;
const {
signature,
error,
error: errorSig,
} = await ConnectionService.post({
action: 'metamask.eip712.permit',
data: {
nonce,
expiry,
allowed: requestedAllowance
allowed: true,
verifyingContract: linkedTokenAddress,
spender: allowanceSpender,
},
});

if (error) {
if (errorSig || error) {
return {
error,
error: errorSig || error,
};
}

return {
spender: sender,
spender: allowanceSpender,
nonce,
expiry,
allowed; requestedAllowance,
allowed: true,
signature,
};
}
28 changes: 27 additions & 1 deletion packages/extension/src/ui/steps/deposit.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,32 @@ const stepSendViaGSN = {
submitTextKey: 'transaction.send.submit',
};

const stepSendViaGSNPermit = {
name: 'send',
descriptionKey: 'transaction.gsn.send.description',
blockStyle: 'sealed',
tasks: [
{
titleKey: 'transaction.step.create.proof',
run: apis.mock,
},
{
titleKey: 'transaction.step.sign',
run: apis.mock,
},
{
titleKey: 'transaction.step.relay',
run: apis.asset.depositWithPermit,
},
{
titleKey: 'transaction.confirmed',
},
],
showTaskList: true,
autoStart: true,
submitTextKey: 'transaction.send.submit',
};

export default {
gsn: [
stepApproveERC20,
Expand All @@ -138,7 +164,7 @@ export default {
gsnWithPermit: [
stepPermitERC20,
stepConfirmForGSN,
stepSendViaGSN,
stepSendViaGSNPermit,
],

metamask: [
Expand Down
2 changes: 2 additions & 0 deletions packages/extension/src/ui/utils/makeAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ export default async function makeAsset(asset) {
icon,
symbol,
decimals,
supportsPermit,
} = linkedTokenAddress
? makeToken(linkedTokenAddress)
: {};

return {
...assetObj,
supportsPermit,
name,
icon,
symbol,
Expand Down
4 changes: 2 additions & 2 deletions packages/extension/src/ui/views/DepositContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ class DepositContent extends StepContentHelper {
} = this.props;

const currentStepName = steps[currentStep].name;
const approved = steps.every(({ name }) => name !== 'approveERC20')
|| isStepAfter(steps, currentStepName, 'approveERC20');
const approved = steps.every(({ name }) => name !== 'approveERC20' && name !== 'permitERC20')
|| isStepAfter(steps, currentStepName, 'approveERC20') || isStepAfter(steps, currentStepName, 'permitERC20');

const {
name: assetName,
Expand Down
3 changes: 2 additions & 1 deletion packages/protocol/contracts/interfaces/IERC20Permit.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ pragma solidity >=0.5.0 <0.6.0;
* (https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/token/ERC20/IERC20.sol)
* and with an added permit() and mint() function.
*/
interface IERC20Permit {
contract IERC20Permit {

mapping (address => uint) public nonces;
function transfer(address to, uint256 value) external returns (bool);

function approve(address spender, uint256 value) external returns (bool);
Expand Down

0 comments on commit 7741b90

Please sign in to comment.