Skip to content

Commit 3f484fa

Browse files
authored
support ctl4rep (#574)
1 parent eaa9c5e commit 3f484fa

File tree

8 files changed

+428
-178
lines changed

8 files changed

+428
-178
lines changed

docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,18 @@ services:
2626
GRAPH_GRAPHQL_MAX_FIRST: '1000'
2727

2828
ipfs:
29-
image: daostack/test-env-ipfs:3.0.42
29+
image: daostack/test-env-ipfs:3.0.43
3030
ports:
3131
- 5001:5001
3232

3333
postgres:
34-
image: daostack/test-env-postgres:3.0.42
34+
image: daostack/test-env-postgres:3.0.43
3535
ports:
3636
- 9432:5432
3737
environment:
3838
POSTGRES_PASSWORD: 'letmein'
3939

4040
ganache:
41-
image: daostack/test-env-ganache:3.0.42
41+
image: daostack/test-env-ganache:3.0.43
4242
ports:
4343
- 8545:8545

package-lock.json

Lines changed: 170 additions & 173 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@daostack/arc.js",
3-
"version": "0.2.82",
3+
"version": "0.2.83",
44
"description": "",
55
"keywords": [],
66
"main": "dist/lib/index.js",
@@ -67,7 +67,7 @@
6767
]
6868
},
6969
"devDependencies": {
70-
"@daostack/migration": "0.0.1-rc.53-v0",
70+
"@daostack/migration": "0.0.1-rc.55-v1",
7171
"@daostack/subgraph-test-env": "0.0.39-8",
7272
"@types/graphql": "^14.2.2",
7373
"@types/isomorphic-fetch": "^0.0.34",

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export { Reputation, IReputationState, IReputationQueryOptions } from './reputat
1212
export { Reward, IRewardState, IRewardStaticState, IRewardQueryOptions } from './reward'
1313
export { Scheme, ISchemeState, ISchemeStaticState, ISchemeQueryOptions } from './scheme'
1414
export { ReputationFromTokenScheme } from './schemes/reputationFromToken'
15+
export { CTL4RScheme } from './schemes/ctl4rep'
1516
export { IContributionReward} from './schemes/contributionReward'
1617
export { hasCompetitionContract, isCompetitionScheme,
1718
IProposalCreateOptionsCompetition,

src/scheme.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { CompetitionScheme, isCompetitionScheme } from './schemes/competition'
1010
import * as Competition from './schemes/competition'
1111
import * as ContributionReward from './schemes/contributionReward'
1212
import * as ContributionRewardExt from './schemes/contributionRewardExt'
13+
import { CTL4RScheme } from './schemes/ctl4rep'
1314
import * as GenericScheme from './schemes/genericScheme'
1415
import * as GenericSchemeMultiCall from './schemes/genericSchemeMultiCall'
1516
import { ReputationFromTokenScheme } from './schemes/reputationFromToken'
@@ -184,6 +185,7 @@ export class Scheme extends SchemeBase {
184185
public id: Address
185186
public staticState: ISchemeStaticState | null = null
186187
public ReputationFromToken: ReputationFromTokenScheme | null = null
188+
public CTL4R: CTL4RScheme | null = null
187189

188190
constructor(idOrOpts: Address | ISchemeStaticState, public context: Arc) {
189191
super(idOrOpts, context)
@@ -202,6 +204,9 @@ export class Scheme extends SchemeBase {
202204
if (this.staticState.name === 'ReputationFromToken') {
203205
this.ReputationFromToken = new ReputationFromTokenScheme(this)
204206
}
207+
if (this.staticState.name === 'ContinuousLocking4Reputation') {
208+
this.CTL4R = new CTL4RScheme(this)
209+
}
205210
}
206211

207212
/**

src/schemes/base.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
IProposalCreateOptions,
99
IProposalQueryOptions, Proposal } from '../proposal'
1010
import { Address, ICommonQueryOptions, IStateful } from '../types'
11+
import { CTL4RScheme } from './ctl4rep'
1112
import { ReputationFromTokenScheme } from './reputationFromToken'
1213

1314
export interface ISchemeStaticState {
@@ -248,6 +249,7 @@ export abstract class SchemeBase implements IStateful<ISchemeState> {
248249
public id: Address
249250
public staticState: ISchemeStaticState | null = null
250251
public ReputationFromToken: ReputationFromTokenScheme | null = null
252+
public CTL4R: CTL4RScheme | null = null
251253

252254
constructor(idOrOpts: Address | ISchemeStaticState, public context: Arc) {
253255
this.context = context
@@ -283,6 +285,9 @@ export abstract class SchemeBase implements IStateful<ISchemeState> {
283285
if (this.staticState.name === 'ReputationFromToken') {
284286
this.ReputationFromToken = new ReputationFromTokenScheme(this)
285287
}
288+
if (this.staticState.name === 'ContinuousLocking4Reputation') {
289+
this.CTL4R = new CTL4RScheme(this)
290+
}
286291
return state
287292
}
288293
}

src/schemes/ctl4rep.ts

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import BN = require('bn.js')
2+
import { from } from 'rxjs'
3+
import { concatMap } from 'rxjs/operators'
4+
5+
import {
6+
Operation,
7+
toIOperationObservable
8+
} from '../operation'
9+
10+
import { Address } from '../types'
11+
12+
import { Scheme } from '../scheme'
13+
14+
export class CTL4RScheme {
15+
16+
constructor(public scheme: Scheme) {
17+
18+
}
19+
20+
public async getAgreementHash(): Promise<string> {
21+
const contract = await this.getContract()
22+
const result = await contract.methods.getAgreementHash().call()
23+
return result
24+
}
25+
26+
public lock(amount: BN, period: number, batchIndexToLockIn: number, agreementHash: string): Operation<any> {
27+
const mapReceipt = (receipt: any) => {
28+
return receipt
29+
}
30+
31+
const observable = from(this.getContract())
32+
.pipe(
33+
concatMap((contract) => {
34+
let transaction: any
35+
transaction = contract.methods.lock(
36+
amount,
37+
period,
38+
batchIndexToLockIn,
39+
agreementHash
40+
)
41+
const errorHandler = async (error: Error) => {
42+
try {
43+
await transaction.call()
44+
} catch (err) {
45+
throw err
46+
}
47+
return error
48+
}
49+
return this.scheme.context.sendTransaction(transaction, mapReceipt, errorHandler)
50+
})
51+
)
52+
return toIOperationObservable(observable)
53+
}
54+
55+
public extendLocking(extendPeriod: number,
56+
batchIndexToLockIn: number,
57+
lockingId: number,
58+
agreementHash: string): Operation<any> {
59+
const mapReceipt = (receipt: any) => {
60+
return receipt
61+
}
62+
63+
const observable = from(this.getContract())
64+
.pipe(
65+
concatMap((contract) => {
66+
let transaction: any
67+
transaction = contract.methods.extendLocking(
68+
extendPeriod,
69+
batchIndexToLockIn,
70+
lockingId,
71+
agreementHash
72+
)
73+
const errorHandler = async (error: Error) => {
74+
try {
75+
await transaction.call()
76+
} catch (err) {
77+
throw err
78+
}
79+
return error
80+
}
81+
return this.scheme.context.sendTransaction(transaction, mapReceipt, errorHandler)
82+
})
83+
)
84+
return toIOperationObservable(observable)
85+
}
86+
public release(beneficiary: Address, lockingId: number): Operation<any> {
87+
const mapReceipt = (receipt: any) => {
88+
return receipt
89+
}
90+
91+
const observable = from(this.getContract())
92+
.pipe(
93+
concatMap((contract) => {
94+
let transaction: any
95+
transaction = contract.methods.release(
96+
beneficiary,
97+
lockingId
98+
)
99+
const errorHandler = async (error: Error) => {
100+
try {
101+
await transaction.call()
102+
} catch (err) {
103+
throw err
104+
}
105+
return error
106+
}
107+
return this.scheme.context.sendTransaction(transaction, mapReceipt, errorHandler)
108+
})
109+
)
110+
return toIOperationObservable(observable)
111+
}
112+
113+
public async getContract() {
114+
const state = await this.scheme.fetchStaticState()
115+
await this.scheme.context.fetchContractInfos({fetchPolicy: 'network-only'})
116+
const contract = this.scheme.context.getContract(state.address)
117+
return contract
118+
}
119+
120+
public getScheme() {
121+
return this.scheme
122+
}
123+
124+
}

test/scheme-ctl4rep.spec.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import { first } from 'rxjs/operators'
2+
import { Arc, CTL4RScheme } from '../src'
3+
import { newArc } from './utils'
4+
import BN = require('bn.js')
5+
import { createAProposal, getTestAddresses, getTestDAO, voteToPassProposal, waitUntilTrue} from './utils'
6+
import {
7+
IProposalState,
8+
IProposalType,
9+
IProposalStage
10+
} from '../src/proposal'
11+
jest.setTimeout(60000)
12+
/**
13+
* Scheme test
14+
*/
15+
describe('Scheme', () => {
16+
17+
let arc: Arc
18+
let accounts: any
19+
20+
const agreementHash = '0x0000000000000000000000000000000000000001000000000000000000000000'
21+
let continuousLocking4ReputationAddress : any
22+
let dao : any
23+
let proposalToAdd :any
24+
let token :any
25+
beforeAll(async () => {
26+
arc = await newArc()
27+
token = arc.GENToken()
28+
29+
accounts = arc.web3.eth.accounts.wallet
30+
const contractInfoFactory = arc.getContractInfoByName('ContinuousLocking4ReputationFactory', '0.0.1-rc.55')
31+
const continuousLocking4ReputationFactory = arc.getContract(contractInfoFactory.address)
32+
33+
// Avatar _avatar,
34+
// uint256 _reputationReward,
35+
// uint256 _startTime,
36+
// uint256 _batchTime,
37+
// uint256 _redeemEnableTime,
38+
// uint256 _maxLockingBatches,
39+
// uint256 _repRewardConstA,
40+
// uint256 _repRewardConstB,
41+
// uint256 _batchesIndexCap,
42+
// IERC20 _token,
43+
// bytes32 _agreementHash
44+
dao = await getTestDAO()
45+
const startTime = (await arc.web3.eth.getBlock('latest')).timestamp
46+
const redeemEnableTime = startTime + 1000
47+
48+
continuousLocking4ReputationAddress = await continuousLocking4ReputationFactory.methods.createCL4R(
49+
dao.id,
50+
new BN('10000000'),
51+
startTime,
52+
new BN('1000'),
53+
redeemEnableTime,
54+
new BN('12'),
55+
new BN('85000'),
56+
new BN('900'),
57+
new BN('5'),
58+
token.address,
59+
agreementHash
60+
).call()
61+
62+
await continuousLocking4ReputationFactory.methods.createCL4R(
63+
dao.id,
64+
new BN('10000000'),
65+
startTime,
66+
new BN('1000'),
67+
redeemEnableTime,
68+
new BN('12'),
69+
new BN('85000'),
70+
new BN('900'),
71+
new BN('5'),
72+
token.address,
73+
agreementHash
74+
).send({gas: 2000000, from:accounts[0].address})
75+
//now register that to a dao
76+
77+
proposalToAdd = await createAProposal(dao, {
78+
descriptionHash: '',
79+
parametersHash: '0x0000000000000000000000000000000000000000000000000000000000001234',
80+
permissions: '0x0000001f',
81+
scheme: getTestAddresses(arc).base.SchemeRegistrar,
82+
schemeToRegister: continuousLocking4ReputationAddress,
83+
type: IProposalType.SchemeRegistrarAdd
84+
})
85+
// accept the proposal by voting the hell out of it
86+
await voteToPassProposal(proposalToAdd)
87+
await proposalToAdd.execute()
88+
89+
})
90+
91+
it('lock and extend lock', async () => {
92+
// check if proposal is indeed accepted etc
93+
const states: IProposalState[] = []
94+
const lastState = () => states[states.length - 1]
95+
proposalToAdd.state().subscribe(((next: any) => states.push(next)))
96+
97+
await waitUntilTrue(() => {
98+
return lastState() && lastState().stage === IProposalStage.Executed
99+
})
100+
const schemes = await dao.schemes({ where: { address: continuousLocking4ReputationAddress.toLowerCase() } }).pipe(first()).toPromise()
101+
const scheme = schemes[0]
102+
expect(scheme.CTL4R).not.toBeFalsy()
103+
const ctl4r = scheme.CTL4R as CTL4RScheme
104+
await ctl4r.getScheme().context.fetchContractInfos({fetchPolicy: 'network-only'})
105+
expect(await ctl4r.getAgreementHash()).toEqual(agreementHash)
106+
const lockAmount = new BN('300')
107+
await token.approveForStaking(continuousLocking4ReputationAddress.toLowerCase(), lockAmount).send()
108+
await token.mint(accounts[0].address, lockAmount).send()
109+
await arc.fetchContractInfos({fetchPolicy: 'network-only'})
110+
const continuousLocking4ReputationContract = arc.getContract(continuousLocking4ReputationAddress.toLowerCase())
111+
const lockCounterBefore = await continuousLocking4ReputationContract.methods.lockCounter().call()
112+
await ctl4r.lock(lockAmount,1,0,agreementHash).send()
113+
const lockCounterAfter = await continuousLocking4ReputationContract.methods.lockCounter().call()
114+
expect(Number(lockCounterBefore)+1).toEqual(Number(lockCounterAfter))
115+
await ctl4r.extendLocking(2,0,lockCounterAfter,agreementHash).send()
116+
117+
})
118+
})

0 commit comments

Comments
 (0)