verified-network / verified-compound-markets

RWA markets for the Compound protocol
1 stars 4 forks source link

Calls / APIs for web extension #1

Open kallolborah opened 11 months ago

kallolborah commented 11 months ago

Here is a list of the calls to make using the Verified SDK - you need to install the latest version of the verified sdk from npm. And you can simply use the wallet connected to the web extension by Compound to call the verified sdk APIs below.

Note : you need to have whatever collateral you are posting as a user to Compound in your wallet. Collateral can only be assets that is accepted by Compound, so check what they accept and get some of them on goerli for free to test.

Buttons :

  1. Issuer UI - Issue new RWA -> on submit of Asset issuance form

There are two calls to make here - a) issue the bond by calling the bond contract function requestIssue(uint256 amount, address payer, bytes32 collateralName, address collateral)

where, collateral is usually a security token issued on the Verified Network, which is then approved by the issuer's agent (DP) by a call to the factory contract function supportTokens(bytes32 _currency, address _address)

b) call the operator contract to submit issued bond details function submitNewRWA(address asset, address bond, uint256 apy, string memory issuingDocs, uint256 faceValue)

where, asset is the security token used to issue the bond and where, the bond address is emitted when the bond is issued and can be retrieved using the subgraph.

  1. Investor UI - Buy issue [to do : change text from 'Buy issue' to 'Provide collateral']

a) Investor provides collateral to RWA issuer by buying the issued bond by calling the Token contract on the bond address function requestTransaction(uint256 amount, address payer, bytes32 collateralName, address collateralContract)

where, currency is the name of the collateral such as 'DAI' or 'WETH' acceptable on both Compound and Verified.

  1. Issuer UI - Borrow

a) first, issuer posts collateral to Compound by calling the operator contract function postCollateral(address asset, address collateral, uint256 amount)

where, base is always the USDC address on the chain linked to the signed in wallet.

b) then, issuer borrows from Compound by calling the operator contract function borrowBase(address base, uint256 amount)

where, base is always the USDC address on the chain linked to the signed in wallet. This function will only work if sufficient collateral has been posted for the USDC amount requested for borrowing.

  1. Issuer UI - Redeem collateral

a) here, issuer repays the loan to investors by calling the Token contract on the bond address function requestTransaction(uint256 amount, address payer, bytes32 collateralName, address collateralContract)

where, collateral is what was used to buy the bond issued earlier.

  1. Issuer UI - Repay loan

a) issuer repays to Compound by calling the operator contract function repayBase(address base, uint256 amount)

where, base is always the USDC address on the chain linked to the signed in wallet.

  1. Investor UI - Redeem issue [to do : change text from 'Redeem issue' to 'Liquidate collateral']

a) if issuer defaults in redeeming collateral (ie, repaying loan) to investors, then investors can claim the RWA tokens locked in the bond contract by calling the Token contract on the bond address function transferFrom(address sender, address receiver, uint256 tokens)

where, the sender is the investor wallet address, receiver is the Bond token address and amount is bond tokens being redeemed by the investor.

Mohzcrea8me commented 5 months ago

issuingDocs

@kallolborah 1a is handled, b needs issuing docs i believe it's an ipfs link to the docs uploade. which ipfs details should i use?

kallolborah commented 1 month ago

@Mohzcrea8me adding test code for bond liquidation and redemption

// test 14
  it("should liquidate Via-USD tokens (by purchaser)", async () => {

    var BokkyPooBahsDateTime = await BokkyPooBahsDateTimeLibrary.deployed();
    await Bond.link(BokkyPooBahsDateTime);

    var security = await Security.at(securityAddress);

    var factory = await Factory.deployed();
    var viausdBondAddress = await factory.getTokenByNameType(await web3.utils.asciiToHex('VBUSD'), await web3.utils.asciiToHex('ViaBond'));
    var viausdBond = await Bond.at(viausdBondAddress);
    var viausdCashAddress = await factory.getTokenByNameType(await web3.utils.asciiToHex('VCUSD'), await web3.utils.asciiToHex('ViaCash'));
    var viausdCash = await Cash.at(viausdCashAddress);

    console.log("Purchaser Account Via-USD bond token balance before redeeming Via-USD bonds: ", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdBondToken.balanceOf(accounts[2]))));
    console.log("Purchaser Account Via-USD cash token balance before redeeming Via-USD bonds: ", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
    console.log("Purchaser Account security token balance before redeeming Via-USD bonds:", await web3.utils.hexToNumberString(await web3.utils.toHex(await security.balanceOf(accounts[2]))));
    console.log();

    await viausdBondToken.transferFrom(accounts[2], usdTokenAddress, await viausdBondToken.balanceOf(accounts[2]));
    await getFirstEvent(viausdBond.BondLiquidated({fromBlock:1}));

    console.log("Purchaser Account Via-USD bond token balance after redeeming Via-USD bonds: ", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdBondToken.balanceOf(accounts[2]))));
    console.log("Purchaser Account Via-USD cash token balance after redeeming Via-USD bonds: ", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
    console.log("Purchaser Account security token balance after redeeming Via-USD bonds:", await web3.utils.hexToNumberString(await web3.utils.toHex(await security.balanceOf(accounts[2]))));
  });

  //test 15
  it("should send Via-USD cash tokens to Via-USD bond contract and pay out paid in cash tokens by bond purchasers (issuer redemption)", async () => {

    var BokkyPooBahsDateTime = await BokkyPooBahsDateTimeLibrary.deployed();
    await Bond.link(BokkyPooBahsDateTime);

    var factory = await Factory.deployed();

    var viausdBondAddress = await factory.getTokenByNameType(await web3.utils.asciiToHex('VBUSD'), await web3.utils.asciiToHex('ViaBond'));
    var viausdBondName = await web3.utils.hexToUtf8(await factory.getName(viausdBondAddress));
    var viausdBondType = await web3.utils.hexToUtf8(await factory.getType(viausdBondAddress));
    var viausdBond = await Bond.at(viausdBondAddress);

    var viausdCashAddress = await factory.getTokenByNameType(await web3.utils.asciiToHex('VCUSD'), await web3.utils.asciiToHex('ViaCash'));
    var viausdCashName = await web3.utils.hexToUtf8(await factory.getName(viausdCashAddress));
    var viausdCashType = await web3.utils.hexToUtf8(await factory.getType(viausdCashAddress));
    var viausdCash = await Cash.at(viausdCashAddress);

    console.log(viausdBondName, viausdBondType, " contract address:", viausdBondAddress);
    console.log();

    var security = await Security.at(securityAddress);
    await security.whiteList(viausdBondAddress, '20', {from: accounts[5]})
    .then(async()=>{
      await security.approve(viausdBondAddress, '20', {from: accounts[1]})
      .then(async()=>{
        await viausdBond.requestIssue('10', accounts[1], ethers.utils.formatBytes32String("company"), securityAddress);

        await getFirstEvent(factory.TokenCreated({fromBlock:1}));
        const rcpt2 = await factory.getPastEvents('TokenCreated', {fromBlock:'latest'});
        usdTokenAddress = rcpt2[0].returnValues.token; 

        viausdBondToken = await Token.at(usdTokenAddress);
        console.log("Via USD bond token address :", usdTokenAddress);
        console.log("Account Via-USD bond token balance after issue:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdBondToken.balanceOf(accounts[1]))));

        console.log(viausdCashName, viausdCashType, " cash contract address:", viausdCashAddress);
        console.log("Account Via-USD cash token balance before sending ether:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
        console.log();

        await viausdCash.sendTransaction({from:accounts[2], to:viausdCashAddress, value:1e18});

        console.log("Account Via-USD cash token balance after sending ether:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
        console.log("Sending cash tokens to bond token "+usdTokenAddress);

        await viausdCash.transferFrom(accounts[2], usdTokenAddress, '5');
        await getFirstEvent(viausdBond.BondPurchased({fromBlock:1}));

        console.log("Purchaser Account Via-USD cash token balance after sending Via-USD for Via-USD bond purchase:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
        console.log("Purchaser Account Via-USD bond token balance after purchase with Via-USD cash :", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdBondToken.balanceOf(accounts[2]))));
        console.log();

        await viausdCash.sendTransaction({from:accounts[1], to:viausdCashAddress, value:1e18});

        console.log("Issuer Account Via-USD cash token balance before redemption :", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[1]))));
        console.log("Purchaser Account Via-USD cash token balance before redemption :", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
        console.log();

        await viausdCash.transferFrom(accounts[1], usdTokenAddress, await viausdCash.balanceOf(accounts[1]));
        await getFirstEvent(viausdBond.BondRedeemed({fromBlock:1}));

        console.log("Issuer Account Via-USD cash token balance after redemption:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[1]))));
        console.log("Purchaser Account Via-USD cash token balance after redemption:", await web3.utils.hexToNumberString(await web3.utils.toHex(await viausdCash.balanceOf(accounts[2]))));
      })
    })  

  });