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

Upgrade to Arc v58, Rinkeby contract addresses #382

Merged
merged 26 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f6478c4
fix GP params
dkent600 Dec 3, 2018
e68525f
update latest DX contracts, make CR desc hashing optional
dkent600 Dec 3, 2018
873d542
add more support for registering in ExternalLocking
dkent600 Dec 3, 2018
82c03e2
fix lockignToken initialize params
dkent600 Dec 3, 2018
e6f604e
upgrade migration version, clean DAO entries from migraiton json
dkent600 Dec 4, 2018
2a86298
upgrade ganache version to sync with migration package
dkent600 Dec 5, 2018
7075f48
bug fixes, constant ganache addresses, but changed account addresses
dkent600 Dec 6, 2018
15fd775
token test fix
dkent600 Dec 6, 2018
6f70438
activate fix
dkent600 Dec 6, 2018
846f450
add getUserEarnedReputation
dkent600 Dec 8, 2018
7b6c138
add auction.getBidBlocker
dkent600 Dec 8, 2018
6a35f0a
add auction.getUserEarnedReputation
dkent600 Dec 8, 2018
5eca83a
pass options to getUserEarnedReputation
dkent600 Dec 8, 2018
0b06c42
added auction.getBids
dkent600 Dec 8, 2018
3190eb2
cleanup redeeming validation
dkent600 Dec 11, 2018
b2d047c
validate enough GEN to bid
dkent600 Dec 13, 2018
a5d6e87
addded external.hasMgnToActivate
dkent600 Dec 14, 2018
f1cc82f
added locking.getReleasedAmount and getReleases
dkent600 Dec 14, 2018
e2a6497
enable account services when contracts aren't available
dkent600 Dec 15, 2018
db7df38
add getCurrentAuctionId, fix getAuctionTotalBid
dkent600 Dec 19, 2018
9b7e637
tweaked some error messages
dkent600 Dec 21, 2018
df40a87
dynamically get MGM token in hasMgnToActivate
dkent600 Dec 22, 2018
173eb10
make check for isUniversal more robust in DaoCreate.setSchemes
dkent600 Dec 24, 2018
f80dc77
bumpbed package#
dkent600 Dec 24, 2018
3710429
validation message changes
dkent600 Dec 26, 2018
949b54c
Merge branch 'master' into upgradeArc
dkent600 Dec 27, 2018
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
4 changes: 4 additions & 0 deletions config/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"host": "127.0.0.1",
"port": 8546
},
"private": {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is private ? what the diff from ganache ?

Copy link
Contributor Author

@dkent600 dkent600 Dec 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private is the name used for networks with an unknown id. ganache is a special case for a network running with a particular network id that arc.js supplies. So, for example, the user might have ganache running with a unknown network id, but arc.js can't know that it is in fact ganache, so will name it "private".

BTW, "private" is the name used by the migrations package and web3.

"host": "127.0.0.1",
"port": 8545
},
"ganache": {
"host": "127.0.0.1",
"port": 8545
Expand Down
5 changes: 2 additions & 3 deletions lib/accountService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import { promisify } from "es6-promisify";
import { Address } from "./commonTypes";
import { LoggingService } from "./loggingService";
import { IEventSubscription, PubSubEventService } from "./pubSubEventService";
import { Utils, Web3 } from "./utils";
import { UtilsInternal } from "./utilsInternal";
import { Utils } from "./utils";

/**
* Watch for changes in the default account.
Expand Down Expand Up @@ -168,7 +167,7 @@ export class AccountService {
private static networkChangedTimerId: any;

private static async getNetworkId(): Promise<number | undefined> {
const web3 = UtilsInternal.getWeb3Sync();
const web3 = await Utils.getWeb3();
return web3 ?
Number.parseInt(await promisify(web3.version.getNetwork)() as string, 10) as number | undefined : undefined;
}
Expand Down
1 change: 1 addition & 0 deletions lib/contractWrapperBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export abstract class ContractWrapperBase implements IContractWrapper {

const maxGasLimit = await UtilsInternal.computeMaxGasLimit();

// note that Ganache is identified specifically as the one instantiated by arc.js (by the networkId)
if (currentNetwork === "Ganache") {
return maxGasLimit; // because who cares with ganache and we can't get good estimates from it
}
Expand Down
1 change: 1 addition & 0 deletions lib/contractWrapperFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export class ContractWrapperFactory<TWrapper extends IContractWrapper>

const maxGasLimit = await UtilsInternal.computeMaxGasLimit();

// note that Ganache is identified specifically as the one instantiated by arc.js (by the networkId)
if (currentNetwork === "Ganache") {
return maxGasLimit; // because who cares with ganache and we can't get good estimates from it
}
Expand Down
16 changes: 8 additions & 8 deletions lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ export async function InitializeArcJs(options: InitializeArcOptions = {}): Promi
networkName = "private";
}

if (options.watchForAccountChanges) {
await AccountService.initiateAccountWatch();
}

if (options.watchForNetworkChanges) {
await AccountService.initiateNetworkWatch();
}

const optionsDeployedContractAddresses = options.deployedContractAddresses || {};

if (!deployedContractAddresses[networkName] && !optionsDeployedContractAddresses[networkName]) {
Expand All @@ -203,14 +211,6 @@ export async function InitializeArcJs(options: InitializeArcOptions = {}): Promi

await WrapperService.initialize(options);

if (options.watchForAccountChanges) {
await AccountService.initiateAccountWatch();
}

if (options.watchForNetworkChanges) {
await AccountService.initiateNetworkWatch();
}

return web3;
} catch (ex) {
/* tslint:disable-next-line:no-bitwise */
Expand Down
3 changes: 1 addition & 2 deletions lib/scripts/createGenesisDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ interface FounderSpec {
export class GenesisDaoCreator {

constructor(
private web3: Web3,
private network: string) {
private web3: Web3) {
}

public async run(): Promise<void> {
Expand Down
9 changes: 7 additions & 2 deletions lib/utilsInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@ export class UtilsInternal {
*/
public static async lastBlockDate(): Promise<Date> {
const web3 = await Utils.getWeb3();
const block = await promisify((callback: any): any =>
web3.eth.getBlock("latest", callback))() as BlockWithoutTransactionData;
let block;
do {
block = await promisify((callback: any): any =>
web3.eth.getBlock("latest", callback))() as BlockWithoutTransactionData;
}
while (!block);

return new Date(block.timestamp * 1000);
}

Expand Down
126 changes: 114 additions & 12 deletions lib/wrappers/auction4Reputation.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"use strict";
import BigNumber from "bignumber.js";
import { DecodedLogEntry } from "web3";
import { Address, Hash } from "../commonTypes";
import { ContractWrapperFactory } from "../contractWrapperFactory";
import { ArcTransactionResult, IContractWrapperFactory } from "../iContractWrapperBase";
import { SchemeWrapperBase } from "../schemeWrapperBase";
import { TxGeneratingFunctionOptions } from "../transactionService";
import { Utils } from "../utils";
import { UtilsInternal } from "../utilsInternal";
import { EventFetcherFactory, Web3EventService } from "../web3EventService";
import { WrapperService } from "../wrapperService";
import { DaoTokenWrapper } from "./daoToken";
import { StandardTokenWrapper } from "./standardToken";

export class Auction4ReputationWrapper extends SchemeWrapperBase {
Expand Down Expand Up @@ -92,6 +95,7 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {

public async redeem(options: Auction4ReputationRedeemOptions & TxGeneratingFunctionOptions)
: Promise<ArcTransactionResult> {

if (!options.beneficiaryAddress) {
throw new Error("beneficiaryAddress is not defined");
}
Expand All @@ -104,6 +108,33 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
throw new Error("auctionId must be greater than or equal to zero");
}

const bid = await this.getBid(options.beneficiaryAddress, options.auctionId);
if (bid.lte(0)) {
// because the Arc contract will revert in this case
return Promise.resolve(null);
}

const errMsg = await this.getRedeemBlocker(options);

if (errMsg) {
throw new Error(errMsg);
}

this.logContractFunctionCall("Auction4Reputation.redeem", options);

return this.wrapTransactionInvocation("Auction4Reputation.redeem",
options,
this.contract.redeem,
[options.beneficiaryAddress, options.auctionId]
);
}

/**
* Returns reason why can't redeem, or else null if can redeem
* @param lockerAddress
*/
public async getRedeemBlocker(options: Auction4ReputationRedeemOptions): Promise<string | null> {

const redeemEnableTime = await this.getRedeemEnableTime();
const now = await UtilsInternal.lastBlockDate();

Expand All @@ -117,13 +148,7 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
throw new Error("the auction period has not passed");
}

this.logContractFunctionCall("Auction4Reputation.redeem", options);

return this.wrapTransactionInvocation("Auction4Reputation.redeem",
options,
this.contract.redeem,
[options.beneficiaryAddress, options.auctionId]
);
return null;
}

/**
Expand All @@ -133,7 +158,7 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
const amount = new BigNumber(options.amount);

if (amount.lte(0)) {
return "amount must be greater than zero";
return "amount to bid must be greater than zero";
}

const startTime = await this.getAuctionsStartTime();
Expand All @@ -143,6 +168,13 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
if ((now > endTime) || (now < startTime)) {
return "bidding is not within the allowed bidding period";
}

const balance = await DaoTokenWrapper.getGenTokenBalance(await Utils.getDefaultAccount());

if (balance.lt(amount)) {
return "the account has insufficient GEN to bid the requested amount";
}

return null;
}

Expand Down Expand Up @@ -191,7 +223,7 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
}

/**
* get promise of the amount bid on the given auction.
* get promise of the amount the account has bid on the given auction.
* @param bidderAddress
* @param auctionId
*/
Expand All @@ -201,12 +233,69 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
throw new Error("bidderAddress is not defined");
}

if (!Number.isInteger(auctionId)) {
throw new Error("auctionId is not an integer");
}

if (auctionId < 0) {
throw new Error("auctionId must be greater than or equal to zero");
}

this.validateAuctionId(auctionId);

this.logContractFunctionCall("Auction4Reputation.getBid", { bidderAddress, auctionId });
return this.contract.getBid(bidderAddress, auctionId);
}

public async getUserEarnedReputation(options: Auction4ReputationRedeemOptions): Promise<BigNumber> {
if (!options.beneficiaryAddress) {
throw new Error("beneficiaryAddress is not defined");
}

if (!Number.isInteger(options.auctionId)) {
throw new Error("auctionId is not an integer");
}

if (options.auctionId < 0) {
throw new Error("auctionId must be greater than or equal to zero");
}

const bid = await this.getBid(options.beneficiaryAddress, options.auctionId);
// because the Arc contract will revert in this case
if (bid.eq(0)) {
return Promise.resolve(new BigNumber(0));
}

const errMsg = await this.getRedeemBlocker(options);

if (errMsg) {
throw new Error(errMsg);
}

this.logContractFunctionCall("Auction4Reputation.redeem.call", options);

return this.contract.redeem.call(options.beneficiaryAddress, options.auctionId);
}

/**
* get a promise of an array of auction ids and amounts in which the given account has placed a bid,
* or all auctions if beneficiaryAddressis not supplied
* @param beneficiaryAddress optional
*/
public async getBids(beneficiaryAddress?: Address): Promise<Array<GetBidAuctionIdsResult>> {

const filter = beneficiaryAddress ? { _bidder: beneficiaryAddress } : {};

const bids = await this.Bid(filter, { fromBlock: 0 }).get();

return bids.map((bid: DecodedLogEntry<Auction4ReputationBidEventResult>): GetBidAuctionIdsResult => {
return {
amount: bid.args._amount,
auctionId: bid.args._auctionId.toNumber(),
};
});
}

/**
* Get a promise of the first date/time when anything can be redeemed
*/
Expand Down Expand Up @@ -249,6 +338,16 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
this.logContractFunctionCall("Auction4Reputation.auctionReputationReward");
return this.contract.auctionReputationReward();
}

/**
* Return promise of 0-based id of the current auction. Returns a negative number if the auction
* has not yet begun. If auction is over then may return an id for an auction that doesn't exist.
*/
public async getCurrentAuctionId(): Promise<number> {
const auctionPeriod = (await this.getAuctionPeriod()) * 1000;
const auctionsStartTime = (await this.getAuctionsStartTime()).getTime();
return Math.floor((Date.now() - auctionsStartTime) / auctionPeriod);
}
/**
* Get a promise of the number of seconds in a single auction
*/
Expand Down Expand Up @@ -276,9 +375,7 @@ export class Auction4ReputationWrapper extends SchemeWrapperBase {
public async getAuctionTotalBid(auctionId: number): Promise<BigNumber> {
this.validateAuctionId(auctionId);
this.logContractFunctionCall("Auction4Reputation.auctions", { auctionId });
const result = (await this.contract.auctions(new BigNumber(auctionId))) as
{ totalBid: BigNumber };
return result.totalBid;
return this.contract.auctions(new BigNumber(auctionId));
}

protected hydrated(): void {
Expand Down Expand Up @@ -399,3 +496,8 @@ export interface Auction4ReputationRedeemEventResult {
*/
_beneficiary: Address;
}

export interface GetBidAuctionIdsResult {
auctionId: number;
amount: BigNumber;
}
28 changes: 16 additions & 12 deletions lib/wrappers/contributionReward.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class ContributionRewardWrapper extends ProposalGeneratorBase {
: Promise<ArcTransactionProposalResult> {

const defaults = {
descriptionIsHashed: false,
ethReward: "0",
externalToken: "", // must have a value for solidity
externalTokenReward: "0",
Expand Down Expand Up @@ -154,7 +155,7 @@ export class ContributionRewardWrapper extends ProposalGeneratorBase {
eventContext,
this.contract.proposeContributionReward,
[options.avatar,
Utils.SHA3(options.description),
options.descriptionIsHashed ? options.description : Utils.SHA3(options.description),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes a bit more sense to me to pass in whether you Arc.js to hash or not, so by default it would not be hashed, but this is ok too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tibetsprague I did it this way to avoid creating a breaking change. For what it is worth, it has the most convenient option as the default.

reputationChange,
[nativeTokenReward, ethReward, externalTokenReward, options.periodLength, options.numberOfPeriods],
options.externalToken,
Expand Down Expand Up @@ -539,17 +540,16 @@ export class ContributionRewardWrapper extends ProposalGeneratorBase {

private convertProposalPropsArrayToObject(propsArray: Array<any>, proposalId: Hash): ContributionProposal {
return {
beneficiaryAddress: propsArray[6],
contributionDescriptionHash: propsArray[0],
ethReward: propsArray[3],
executionTime: propsArray[9],
externalToken: propsArray[4],
externalTokenReward: propsArray[5],
nativeTokenReward: propsArray[1],
numberOfPeriods: propsArray[8],
periodLength: propsArray[7],
beneficiaryAddress: propsArray[5],
ethReward: propsArray[2],
executionTime: propsArray[8],
externalToken: propsArray[3],
externalTokenReward: propsArray[4],
nativeTokenReward: propsArray[0],
numberOfPeriods: propsArray[7],
periodLength: propsArray[6],
proposalId,
reputationChange: propsArray[2],
reputationChange: propsArray[1],
};
}
}
Expand Down Expand Up @@ -587,7 +587,6 @@ export interface NewContributionProposalEventResult {
export interface ContributionProposal {
proposalId: Hash;
beneficiaryAddress: Address;
contributionDescriptionHash: Hash;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this get removed?

Copy link
Contributor Author

@dkent600 dkent600 Dec 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tibetsprague I forgot about that. I've added it to the list of breaking changes above. That property was removed from the contract as part of this PR: https://github.com/daostack/arc/pull/561/files

ethReward: BigNumber;
executionTime: number;
externalToken: Address;
Expand Down Expand Up @@ -747,6 +746,11 @@ export interface ProposeContributionRewardParams {
* beneficiary address
*/
beneficiaryAddress: string;
/**
* True if description is a hashed, false if not and in which case Arc.js will hash it.
* The default is false.
*/
descriptionIsHashed?: boolean;
}

export interface ContributionRewardRedeemParams {
Expand Down
Loading