Skip to content
This repository has been archived by the owner on Sep 28, 2022. It is now read-only.

Commit

Permalink
Merge branch 'dev' of https://github.com/makerdao/dai.js into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
b-pmcg committed Feb 13, 2020
2 parents 5df4f65 + 3cb107b commit 3f25c8b
Show file tree
Hide file tree
Showing 18 changed files with 436 additions and 117 deletions.
1 change: 1 addition & 0 deletions packages/dai-plugin-governance/contracts/abis/DSSpell.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"constant":true,"inputs":[],"name":"SAIMOM","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SCDCAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"action","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"cast","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"done","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"eta","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"pause","outputs":[{"internalType":"contract DSPauseAbstract","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"schedule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"sig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tag","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"}]
9 changes: 9 additions & 0 deletions packages/dai-plugin-governance/contracts/contract-info.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@
"lock": "0xdd46706400000000000000000000000000000000000000000000000000000000"
}
},
"pause": {
"inception_block": {
"mainnet": "8928171",
"kovan": "14764552"
},
"events": {
"exec": "0x168ccd6700000000000000000000000000000000000000000000000000000000"
}
},
"proxy_factory": {
"initiate_link_gas": 45840,
"approve_link_gas": 886503,
Expand Down
2 changes: 1 addition & 1 deletion packages/dai-plugin-governance/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@makerdao/dai-plugin-governance",
"description": "A dai.js plugin for adding MKR governance support to dapps.",
"version": "0.9.2",
"version": "0.9.4",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
22 changes: 0 additions & 22 deletions packages/dai-plugin-governance/src/PauseService.js

This file was deleted.

96 changes: 96 additions & 0 deletions packages/dai-plugin-governance/src/SpellService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { PublicService } from '@makerdao/services-core';
import { PAUSE } from './utils/constants';
import DsSpellAbi from '../contracts/abis/DSSpell.json';
import padStart from 'lodash/padStart';
import assert from 'assert';
import contractInfo from '../contracts/contract-info.json';
const pauseInfo = contractInfo.pause;
import { netIdToName } from './utils/helpers';

export default class SpellService extends PublicService {
constructor(name = 'spell') {
super(name, ['smartContract', 'web3']);
this.eta = {};
this.done = {};
this.action = {};
this.executionDate = {};
}

getDelayInSeconds() {
if (this.delay) return this.delay;
this.delay = this._pauseContract().delay();
return this.delay;
}

async getEta(spellAddress) {
if (this.eta[spellAddress]) return this.eta[spellAddress];
const spell = this.get('smartContract').getContractByAddressAndAbi(
spellAddress,
DsSpellAbi
);
const eta = await spell.eta();
if (!eta.toNumber()) return undefined;
this.eta[spellAddress] = new Date(eta.toNumber() * 1000);
return this.eta[spellAddress];
}

async getScheduledDate(spellAddress) {
const delay = await this.getDelayInSeconds();
const eta = await this.getEta(spellAddress);
assert(eta, `spell ${spellAddress} has not been scheduled yet`);
return new Date(eta.getTime() - delay * 1000);
}

async getDone(spellAddress) {
if (this.done[spellAddress]) return this.done[spellAddress];
const spell = this.get('smartContract').getContractByAddressAndAbi(
spellAddress,
DsSpellAbi
);
this.done[spellAddress] = spell.done();
return this.done[spellAddress];
}

async getAction(spellAddress) {
if (this.action[spellAddress]) return this.action[spellAddress];
const spell = this.get('smartContract').getContractByAddressAndAbi(
spellAddress,
DsSpellAbi
);
this.action[spellAddress] = spell.action();
return this.action[spellAddress];
}

async getExecutionDate(spellAddress) {
if (this.executionDate[spellAddress])
return this.executionDate[spellAddress];
const done = await this.getDone(spellAddress);
assert(done, `spell ${spellAddress} has not been executed`);
const pauseAddress = this._pauseContract().address;
const web3Service = this.get('web3');
const netId = web3Service.network;
const networkName = netIdToName(netId);
const paddedSpellAddress =
'0x' + padStart(spellAddress.replace(/^0x/, ''), 64, '0');
const [execEvent] = await web3Service.getPastLogs({
fromBlock: pauseInfo.inception_block[networkName],
toBlock: 'latest',
address: pauseAddress,
topics: [pauseInfo.events.exec, paddedSpellAddress]
});
const { timestamp } = await web3Service.getBlock(execEvent.blockNumber);
this.executionDate[spellAddress] = new Date(timestamp * 1000);
return this.executionDate[spellAddress];
}

refresh() {
this.delay = null;
this.eta = {};
this.done = {};
this.executionDate = {};
}

_pauseContract() {
return this.get('smartContract').getContractByName(PAUSE);
}
}
6 changes: 3 additions & 3 deletions packages/dai-plugin-governance/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import VoteProxyFactoryService from './VoteProxyFactoryService';
import GovPollingService from './GovPollingService';
import GovQueryApiService from './GovQueryApiService';
import EsmService from './EsmService';
import PauseService from './PauseService';
import SpellService from './SpellService';

export default {
addConfig: function(config, { network = 'mainnet', staging = false }) {
Expand Down Expand Up @@ -74,15 +74,15 @@ export default {
'govPolling',
'govQueryApi',
'esm',
'pause'
'spell'
],
chief: [ChiefService],
voteProxy: [VoteProxyService],
voteProxyFactory: [VoteProxyFactoryService],
govPolling: [GovPollingService],
govQueryApi: [GovQueryApiService, { staging }],
esm: [EsmService],
pause: [PauseService],
spell: [SpellService],
smartContract: { addContracts },
token: {
erc20: [
Expand Down
36 changes: 0 additions & 36 deletions packages/dai-plugin-governance/test/PauseService.test.js

This file was deleted.

81 changes: 81 additions & 0 deletions packages/dai-plugin-governance/test/SpellService.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
setupTestMakerInstance,
restoreSnapshotOriginal,
sleep
} from './helpers';

let maker, spellService;

afterAll(async done => {
if (global.useOldChain) {
await restoreSnapshotOriginal(global.snapshotId);
done();
} else {
global.client.restoreSnapshot(global.testchainId, global.defaultSnapshotId);
await sleep(15000);

await global.client.delete(global.testchainId);
await sleep(15000);

done();
}
});

//NOTE: these tests use mainnet instead of the testchain, because the
// testchain doesn't have spells (that have been executed) yet
describe('use mainnet', () => {
beforeAll(async () => {
maker = await setupTestMakerInstance('mainnet');
spellService = maker.service('spell');
});

test('get spell execution date', async () => {
const date = await spellService.getExecutionDate(
'0x48916a2b11fa7a895426eedf9acf2d70523b1677'
);
expect(date).toEqual(new Date('2020-02-04T11:35:48.000Z'));
});

test('get spell eta', async () => {
const eta = await spellService.getEta(
'0xf880d43bb9a32dd212c77b82a7336be31ecaee08'
);
expect(eta).toEqual(new Date('2020-01-26T11:53:19.000Z'));
});

test('get spell done boolean', async () => {
const done = await spellService.getDone(
'0xf880d43bb9a32dd212c77b82a7336be31ecaee08'
);
expect(done).toBe(true);
});

test('get spell action address', async () => {
const action = await spellService.getAction(
'0xf880d43bb9a32dd212c77b82a7336be31ecaee08'
);
expect(action).toBe('0x68D4e46c1ca8a346f82e36f324A9C0935041De79');
});
});

describe('use testchain', () => {
beforeAll(async () => {
maker = await setupTestMakerInstance();
spellService = maker.service('spell');
});

test('get delay', async () => {
const delay = await spellService.getDelayInSeconds();
expect(delay.toNumber()).toBe(1);
});

test('get date spell was scheduled', async () => {
const mockGetEta = jest.fn(() => new Date('2020-02-04T11:35:48.000Z'));
const tempGetEta = spellService.getEta;
spellService.getEta = mockGetEta;
const date = await spellService.getScheduledDate('mockSpellAddress');
expect(mockGetEta).toBeCalled();
expect(date).toEqual(new Date('2020-02-04T11:35:47.000Z')); //1 second before eta
spellService.getEta = tempGetEta;
});
});
2 changes: 1 addition & 1 deletion packages/dai-plugin-mcd/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@makerdao/dai-plugin-mcd",
"description": "Plugin to add Multi-Collateral Dai support to dai.js",
"version": "1.1.0-rc.1",
"version": "1.1.0",
"license": "MIT",
"main": "dist",
"scripts": {
Expand Down
49 changes: 42 additions & 7 deletions packages/dai-plugin-mcd/src/schemas/computed.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ import {
PROXY_OWNER,
ANNUAL_DAI_SAVINGS_RATE,
DAI_SAVINGS_RATE,
DATE_EARNINGS_LAST_ACCRUED
DATE_EARNINGS_LAST_ACCRUED,
USER_VAULT_IDS,
USER_VAULT_ADDRESSES,
USER_VAULT_TYPES
} from './constants';

export const collateralTypePrice = {
Expand Down Expand Up @@ -325,7 +328,6 @@ export const balance = {
}
return [[TOKEN_BALANCE, address, symbol]];
},
demarcate: true,
computed: v => v
})
};
Expand All @@ -335,7 +337,6 @@ export const allowance = {
dependencies: [
[TOKEN_ALLOWANCE, address, [PROXY_ADDRESS, address], symbol]
],
demarcate: true,
computed: v => v.isEqualTo(ALLOWANCE_AMOUNT)
})
};
Expand All @@ -347,24 +348,57 @@ export const savings = {
[DAI_SAVINGS_RATE],
[DATE_EARNINGS_LAST_ACCRUED],
[DAI_LOCKED_IN_DSR, address],
[PROXY_ADDRESS, address]
[PROXY_ADDRESS, address],
[SAVINGS_RATE_ACCUMULATOR],
[SAVINGS_DAI, [PROXY_ADDRESS, address]]
],
computed: (
annualDaiSavingsRate,
daiSavingsRate,
dateEarningsLastAccrued,
daiLockedInDsr,
proxyAddress
proxyAddress,
savingsRateAccumulator,
savingsDai
) => ({
annualDaiSavingsRate,
daiSavingsRate,
dateEarningsLastAccrued,
daiLockedInDsr,
proxyAddress
proxyAddress,
savingsRateAccumulator,
savingsDai
})
})
};

export const userVaultsList = {
generate: address => ({
dependencies: ({ get }) => {
const cdpManagerAddress = get('smartContract').getContractAddress(
'CDP_MANAGER'
);
return [
[USER_VAULT_IDS, cdpManagerAddress, [PROXY_ADDRESS, address]],
[USER_VAULT_ADDRESSES, cdpManagerAddress, [PROXY_ADDRESS, address]],
[USER_VAULT_TYPES, cdpManagerAddress, [PROXY_ADDRESS, address]]
];
},
computed: (ids, addresses, types) =>
ids.reduce(
(acc, id, idx) => [
...acc,
{
vaultId: id,
vaultAddress: addresses[idx],
vaultType: types[idx]
}
],
[]
)
})
};

export default {
collateralTypePrice,
collateralTypesPrices,
Expand All @@ -385,5 +419,6 @@ export default {
totalDaiLockedInDsr,
balance,
allowance,
savings
savings,
userVaultsList
};
Loading

0 comments on commit 3f25c8b

Please sign in to comment.