DCIPs/assets/eip-3475/ERC3475.test.ts

334 lines
12 KiB
TypeScript

// @notice : run the typechain generate commance into the smrt contract repository (truffle in our case), after the contracts are compiled.
import { ERC3475Instance } from "../types/truffle-contracts";
function sleep(ms: any) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
const Bond = artifacts.require("ERC3475");
contract('Bond', async (accounts: string[]) => {
let bondContract: ERC3475Instance;
const lender = accounts[1];
const operator = accounts[2];
const secondaryMarketBuyer = accounts[3];
const secondaryMarketBuyer2 = accounts[4];
const spender = accounts[5];
const DBITClassId: number = 0;
const firstNonceId: number = 0;
interface _transaction {
classId: string | number | BN;
nonceId: string | number | BN;
amount: string | number | BN;
}
before('testing', async () => {
bondContract = await Bond.deployed();
})
it('should issue bonds to a lender', async () => {
let _transactionIssuer: _transaction[]
=
[{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 7000
}];
await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
const balance = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()
const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber()
assert.equal(balance, 14000);
assert.equal(activeSupply, 14000);
})
it('lender should be able to transfer bonds to another address', async () => {
const transferBonds: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 2000
}];
await bondContract.transferFrom(lender, secondaryMarketBuyer, transferBonds, { from: lender })
const lenderBalance = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()
const secondaryBuyerBalance = (await bondContract.balanceOf(secondaryMarketBuyer, DBITClassId, firstNonceId)).toNumber()
const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber()
assert.equal(lenderBalance, 12000);
assert.equal(secondaryBuyerBalance, 2000);
assert.equal(activeSupply, 14000);
})
it('operator should be able to manipulate bonds after approval', async () => {
const transactionApproval: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 2000
}];
await bondContract.setApprovalFor(operator, true, { from: lender })
const isApproved = await bondContract.isApprovedFor(lender, operator);
assert.isTrue(isApproved);
await bondContract.transferFrom(lender, secondaryMarketBuyer2, transactionApproval, { from: operator })
expect((await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber()).to.equal(10000);
expect((await bondContract.balanceOf(secondaryMarketBuyer2, DBITClassId, firstNonceId)).toNumber()).to.equal(2000);
})
it('lender should redeem bonds when conditions are met', async () => {
const redemptionTransaction: _transaction[] = [
{
classId: 1,
nonceId: 1,
amount: 2000
},
];
await bondContract.issue(accounts[2],redemptionTransaction, {from: accounts[2]});
assert.equal((await bondContract.balanceOf(accounts[2], 1, 1)).toNumber(), 2000);
// adding delay for passing the redemption time period.
await sleep(7000);
await bondContract.redeem(accounts[2], redemptionTransaction, {from:accounts[2]});
assert.equal((await bondContract.balanceOf(accounts[2], DBITClassId, firstNonceId)).toNumber(), 0);
})
it('lender should not be able to redeem bonds when conditions are not met', async () => {
const redemptionTransaction: _transaction[] = [
{
classId: 0,
nonceId: 0,
amount: 2000
},
];
await bondContract.issue(accounts[2],redemptionTransaction, {from: accounts[2]});
assert.equal((await bondContract.balanceOf(accounts[2], 0, 0)).toNumber(), 2000);
try {
await bondContract.redeem(accounts[2], redemptionTransaction, {from:accounts[2]});
}
catch(e:any){
assert.isTrue(true);
}
})
//////////////////// UNIT TESTS //////////////////////////////
it('should transfer bonds from an caller address to another', async () => {
const transactionTransfer: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 500
}];
await bondContract.issue(lender, transactionTransfer, { from: lender });
const tx = (await bondContract.transferFrom(lender, secondaryMarketBuyer, transactionTransfer, {from:lender})).tx;
console.log(tx)
assert.isString(tx);
})
it('should issue bonds to a given address', async () => {
const transactionIssue: _transaction[] = [
{
classId: 1,
nonceId: firstNonceId,
amount: 500
}
];
const tx = (await bondContract.issue(lender, transactionIssue)).tx;
console.log(tx)
assert.isString(tx);
})
it('should redeem bonds from a given address', async () => {
const transactionRedeem: _transaction[] = [
{
classId: 1,
nonceId: firstNonceId,
amount: 500
}];
await bondContract.issue(lender, transactionRedeem, {from: lender});
sleep(7000);
const tx = (await bondContract.redeem(lender, transactionRedeem, {from:lender})).tx;
console.log(tx)
assert.isString(tx);
})
it('should burn bonds from a given address', async () => {
const transactionRedeem: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 500
}];
await bondContract.issue(lender, transactionRedeem, {from: lender});
const tx = (await bondContract.burn(lender, transactionRedeem, {from:lender})).tx;
console.log(tx)
assert.isString(tx);
})
it('should approve spender to manage a given amount of bonds from the caller address', async () => {
const transactionApprove: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 500
}];
await bondContract.issue(lender, transactionApprove, {from: lender});
const tx = (await bondContract.approve(spender, transactionApprove)).tx;
console.log(tx)
assert.isString(tx);
})
it('setApprovalFor (called by bond owner) should be able to give operator permissions to manage bonds for given classId', async () => {
const tx = (await bondContract.setApprovalFor(operator, true, { from: lender })).tx;
console.log(tx)
assert.isString(tx);
})
it('should batch approve', async () => {
const transactionApprove: _transaction[] = [
{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 500
},
{ classId: 1, nonceId: 0, amount: 900 }
];
await await bondContract.issue(spender,transactionApprove, {from:spender});
const tx = (await bondContract.approve(spender, transactionApprove, {from:spender})).tx;
console.log(tx)
assert.isString(tx);
})
it('should return the active supply', async () => {
const activeSupply = (await bondContract.activeSupply(DBITClassId, firstNonceId)).toNumber();
console.log(activeSupply)
assert.isNumber(activeSupply);
})
it('should return the redeemed supply', async () => {
const redeemedSupply = (await bondContract.redeemedSupply(DBITClassId, firstNonceId)).toNumber();
console.log(redeemedSupply)
assert.isNumber(redeemedSupply);
})
it('should return the burned supply', async () => {
const burnedSupply = (await bondContract.burnedSupply(DBITClassId, firstNonceId)).toNumber();
console.log(burnedSupply)
assert.isNumber(burnedSupply);
})
it('should return the total supply', async () => {
const totalSupply = (await bondContract.totalSupply(DBITClassId, firstNonceId)).toNumber();
console.log(totalSupply)
assert.isNumber(totalSupply);
})
it('should return the balanceOf a bond of a given address', async () => {
const balanceOf = (await bondContract.balanceOf(lender, DBITClassId, firstNonceId)).toNumber();
console.log(balanceOf)
assert.isNumber(balanceOf);
})
it('should return the symbol of a class of bond', async () => {
let metadataId = 0;
const symbol: {
stringValue: string;
uintValue: BN;
addressValue: string;
boolValue: boolean;
} = (await bondContract.classValues(DBITClassId, metadataId));
console.log(JSON.stringify(symbol));
assert.isString(symbol.stringValue);
})
it('should return the Values for given bond class', async () => {
const metadataId = 0;
let _transactionIssuer: _transaction[]
=
[{
classId: DBITClassId,
nonceId: firstNonceId,
amount: 7000
}];
await bondContract.issue(lender, _transactionIssuer, { from: accounts[0] })
const valuesClass = (await bondContract.classValues(DBITClassId, metadataId));
console.log("class infos: ", JSON.stringify(valuesClass));
assert.isString(valuesClass.toString());
})
it('should return the infos of a nonce for given bond class', async () => {
const metadataId = 0;
const infos = (await bondContract.nonceValues(DBITClassId, firstNonceId, metadataId));
console.log("nonce infos: ", JSON.stringify(infos))
assert.isString(infos.toString());
})
it('should return if an operator is approved on a class and nonce given for an address', async () => {
const isApproved = (await bondContract.isApprovedFor(lender, operator));
console.log("operator is Approved? : ", isApproved)
assert.isBoolean(isApproved);
})
it('should return if its redeemable', async () => {
let _transactionIssuer: _transaction[]
=
[{
classId: 1,
nonceId: 1,
amount: 7000
}];
await bondContract.issue(accounts[1], _transactionIssuer, { from: accounts[1] })
const getProgress = await bondContract.getProgress(1,1);
console.log("is Redeemable? : ", getProgress[1].toNumber() >= 0)
assert.isNumber(getProgress[1].toNumber());
})
it('should set allowance of a spender', async () => {
const allowance = (await bondContract.allowance(lender, spender, DBITClassId, firstNonceId, {from:lender})).toNumber();
console.log("allowance : ", allowance)
assert.isNumber(allowance);
})
it('should return if operator is approved for', async () => {
const isApproved = (await bondContract.isApprovedFor(lender, operator));
console.log("operator is Approved? : ", isApproved)
assert.isTrue(isApproved);
})
});