-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add createLoanScheme rpc * Add setDefaultLoanScheme rpc * Revert "Add setDefaultLoanScheme rpc" This reverts commit 0a291de * Add createVault rpc * Revert "Add createVault rpc" This reverts commit 400ed1a * Add setLoanToken rpc * Resolve merge conflicts * Improve code * Improve code * Improve code * Minor * Minor * Fix doc * Add afterAll function * Fix wrong doc * Minor * Change docker image * Quick push * Improve code * Improve code * Minor * Set mintable default to false * PriceFeed must have USD currency * CollateralToken's priceFeed should contain USD price * Improve code * Fix wrong text * Update docker image for DFTX * Apply code changes as per code review * Apply code changes as per code review * Change lesser to less * Fix wrong text * Apply code changes as per code review * Apply code changes as per code review * Apply code changes as per code review * To handle 2 loan tokens have the same name * Update to latest docker image as mintable default = true fix is just merged to epic/loan * Update packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts committing since a name change. Co-authored-by: surangap <[email protected]>
- Loading branch information
1 parent
ee7767c
commit a370953
Showing
7 changed files
with
384 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
327 changes: 327 additions & 0 deletions
327
packages/jellyfish-api-core/__tests__/category/loan/setLoanToken.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
import { LoanMasterNodeRegTestContainer } from './loan_container' | ||
import BigNumber from 'bignumber.js' | ||
import { Testing } from '@defichain/jellyfish-testing' | ||
import { GenesisKeys } from '@defichain/testcontainers' | ||
|
||
describe('Loan', () => { | ||
const container = new LoanMasterNodeRegTestContainer() | ||
const testing = Testing.create(container) | ||
|
||
beforeAll(async () => { | ||
await testing.container.start() | ||
await testing.container.waitForWalletCoinbaseMaturity() | ||
}) | ||
|
||
afterAll(async () => { | ||
await testing.container.stop() | ||
}) | ||
|
||
it('should setLoanToken', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token1', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token1', | ||
priceFeedId | ||
}) | ||
expect(typeof loanTokenId).toStrictEqual('string') | ||
expect(loanTokenId.length).toStrictEqual(64) | ||
await testing.generate(1) | ||
|
||
const data = await testing.container.call('listloantokens', []) | ||
expect(data).toStrictEqual({ | ||
[loanTokenId]: { | ||
token: { | ||
1: { | ||
symbol: 'Token1', | ||
symbolKey: 'Token1', | ||
name: '', | ||
decimal: 8, | ||
limit: 0, | ||
mintable: true, | ||
tradeable: true, | ||
isDAT: true, | ||
isLPS: false, | ||
finalized: false, | ||
isLoanToken: true, | ||
minted: 0, | ||
creationTx: loanTokenId, | ||
creationHeight: await testing.container.getBlockCount(), | ||
destructionTx: '0000000000000000000000000000000000000000000000000000000000000000', | ||
destructionHeight: -1, | ||
collateralAddress: expect.any(String) | ||
} | ||
}, | ||
priceFeedId, | ||
interest: 0 | ||
} | ||
}) | ||
}) | ||
|
||
it('should setLoanToken if symbol is more than 8 letters', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'x'.repeat(8), | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'x'.repeat(9), // 9 letters | ||
priceFeedId | ||
}) | ||
await testing.generate(1) | ||
|
||
const data = await testing.container.call('listloantokens', []) | ||
const index = Object.keys(data).indexOf(loanTokenId) + 1 | ||
expect(data[loanTokenId].token[index].symbol).toStrictEqual('x'.repeat(8)) // Only remain the first 8 letters | ||
}) | ||
|
||
it('should not setLoanToken if symbol is an empty string', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token2', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: '', | ||
priceFeedId | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Test LoanSetLoanTokenTx execution failed:\ntoken symbol should be non-empty and starts with a letter\', code: -32600, method: setloantoken') | ||
}) | ||
|
||
it('should not setLoanToken if token with same symbol was created before', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token3', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token3', | ||
priceFeedId | ||
}) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token3', | ||
priceFeedId | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Test LoanSetLoanTokenTx execution failed:\ntoken \'Token3\' already exists!\', code: -32600, method: setloantoken') | ||
}) | ||
|
||
it('should not setLoanToken if priceFeedId does not contain USD price', async () => { | ||
const priceFeedId: string = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token4', | ||
currency: 'Token4' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token4', | ||
priceFeedId | ||
}) | ||
await expect(promise).rejects.toThrow(`RpcApiError: 'Test LoanSetLoanTokenTx execution failed:\noracle (${priceFeedId}) does not contain USD price for this token!', code: -32600, method: setloantoken`) | ||
}) | ||
|
||
it('should not setLoanToken if priceFeedId is invalid', async () => { | ||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token5', | ||
priceFeedId: 'e40775f8bb396cd3d94429843453e66e68b1c7625d99b0b4c505ab004506697b' | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Test LoanSetLoanTokenTx execution failed:\noracle (e40775f8bb396cd3d94429843453e66e68b1c7625d99b0b4c505ab004506697b) does not exist or not valid oracle!\', code: -32600, method: setloantoken') | ||
}) | ||
|
||
it('should setLoanToken with the given name', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token6', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token6', | ||
name: 'Token6', | ||
priceFeedId | ||
}) | ||
await testing.generate(1) | ||
|
||
const data = await testing.container.call('listloantokens', []) | ||
const index = Object.keys(data).indexOf(loanTokenId) + 1 | ||
expect(data[loanTokenId].token[index].name).toStrictEqual('Token6') | ||
}) | ||
|
||
it('should setLoanToken if name is more than 128 letters', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token7', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token7', | ||
name: 'x'.repeat(129), // 129 letters | ||
priceFeedId | ||
}) | ||
await testing.generate(1) | ||
|
||
const data = await testing.container.call('listloantokens', []) | ||
const index = Object.keys(data).indexOf(loanTokenId) + 1 | ||
expect(data[loanTokenId].token[index].name).toStrictEqual('x'.repeat(128)) // Only remain the first 128 letters. | ||
}) | ||
|
||
it('should setLoanToken if two loan tokens have the same name', async () => { | ||
const priceFeedId1 = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token8', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token8', | ||
name: 'TokenX', | ||
priceFeedId: priceFeedId1 | ||
}) | ||
await testing.generate(1) | ||
|
||
const priceFeedId2 = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token9', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token9', | ||
name: 'TokenX', | ||
priceFeedId: priceFeedId2 | ||
}) | ||
await testing.generate(1) | ||
|
||
expect(typeof loanTokenId).toStrictEqual('string') | ||
expect(loanTokenId.length).toStrictEqual(64) | ||
await testing.generate(1) | ||
}) | ||
|
||
it('should setLoanToken if mintable is false', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token10', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token10', | ||
priceFeedId, | ||
mintable: false | ||
}) | ||
expect(typeof loanTokenId).toStrictEqual('string') | ||
expect(loanTokenId.length).toStrictEqual(64) | ||
await testing.generate(1) | ||
}) | ||
|
||
it('should setLoanToken if interest number is greater than 0 and has less than 9 digits in the fractional part', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token11', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token11', | ||
priceFeedId, | ||
interest: new BigNumber(15.12345678) // 8 digits in the fractional part | ||
}) | ||
expect(typeof loanTokenId).toStrictEqual('string') | ||
expect(loanTokenId.length).toStrictEqual(64) | ||
await testing.generate(1) | ||
}) | ||
|
||
it('should not setLoanToken if interest number is greater than 0 and has more than 8 digits in the fractional part', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token12', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token12', | ||
priceFeedId, | ||
interest: new BigNumber(15.123456789) // 9 digits in the fractional part | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Invalid amount\', code: -3, method: setloantoken') | ||
}) | ||
|
||
it('should not setLoanToken if interest number is less than 0', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token13', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token13', | ||
priceFeedId, | ||
interest: new BigNumber(-15.12345678) | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Amount out of range\', code: -3, method: setloantoken') | ||
}) | ||
|
||
it('should not setLoanToken if interest number is greater than 1200000000', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token14', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token14', | ||
priceFeedId, | ||
interest: new BigNumber('1200000000').plus('0.00000001') | ||
}) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Amount out of range\', code: -3, method: setloantoken') | ||
}) | ||
|
||
it('should setLoanToken with utxos', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token15', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const { txid, vout } = await testing.container.fundAddress(GenesisKeys[0].owner.address, 10) | ||
const loanTokenId = await testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token15', | ||
priceFeedId | ||
}, [{ txid, vout }]) | ||
expect(typeof loanTokenId).toStrictEqual('string') | ||
expect(loanTokenId.length).toStrictEqual(64) | ||
await testing.generate(1) | ||
|
||
const rawtx = await testing.container.call('getrawtransaction', [loanTokenId, true]) | ||
expect(rawtx.vin[0].txid).toStrictEqual(txid) | ||
expect(rawtx.vin[0].vout).toStrictEqual(vout) | ||
|
||
const data = await testing.container.call('listloantokens', []) | ||
const index = Object.keys(data).indexOf(loanTokenId) + 1 | ||
expect(data[loanTokenId].token[index].symbol).toStrictEqual('Token15') | ||
expect(data[loanTokenId].token[index].name).toStrictEqual('') | ||
}) | ||
|
||
it('should not setLoanToken with utxos not from foundation member', async () => { | ||
const priceFeedId = await testing.container.call('appointoracle', [await testing.generateAddress(), [{ | ||
token: 'Token16', | ||
currency: 'USD' | ||
}], 1]) | ||
await testing.generate(1) | ||
|
||
const utxo = await testing.container.fundAddress(await testing.generateAddress(), 10) | ||
const promise = testing.rpc.loan.setLoanToken({ | ||
symbol: 'Token16', | ||
priceFeedId | ||
}, [utxo]) | ||
await expect(promise).rejects.toThrow('RpcApiError: \'Test LoanSetLoanTokenTx execution failed:\ntx not from foundation member!\', code: -32600, method: setloantoken') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.