text: const { assert } = require("chai");
  // const hre = require("hardhat"); access to the hardhat engine if needed
  // const { encodeParameters, etherMantissa, mineBlock, increaseTime, blockNumber, sendFallback } = require("./utilities/ethereum"); useful utilities
  
  const LoanTokenLogicStandard = artifacts.require("LoanTokenLogicStandard");
  const sovrynProtocol = artifacts.require("sovrynProtocol");
  const LoanToken = artifacts.require("LoanToken");
  
  const TestWrbtc = artifacts.require("TestWrbtc");
  const TestToken = artifacts.require("TestToken");
  const ISovryn = artifacts.require("ISovryn");
  const ProtocolSettings = artifacts.require("ProtocolSettings");
  const LoanSettings = artifacts.require("LoanSettings");
  const LoanMaintenance = artifacts.require("LoanMaintenance");
  const LoanOpenings = artifacts.require("LoanOpenings");
  const SwapsExternal = artifacts.require("SwapsExternal");
  const LoanClosingsBase = artifacts.require("LoanClosingsBase");
  const LoanClosingsWith = artifacts.require("LoanClosingsWith");
  
  const PriceFeedsLocal = artifacts.require("PriceFeedsLocal");
  const TestSovrynSwap = artifacts.require("TestSovrynSwap");
  const SwapsImplLocal = artifacts.require("SwapsImplLocal");
  const Affiliates = artifacts.require("Affiliates");
  
  const { BN, constants, balance, expectEvent, expectRevert } = require("@openzeppelin/test-helpers");
  const { expect } = require("hardhat");
  
  contract("Margin Trading with Affiliates boilerplate", (accounts) => {
  	let loanTokenLogic;
  	let testWrbtc;
  	let doc;
  	let sovryn;
  	let loanTokenV2;
  	let wei = web3.utils.toWei;
  	before(async () => {
  		[owner, trader, referrer, account1, account2, ...accounts] = accounts;
  	});
  	beforeEach(async () => {
  		loanTokenLogic = await LoanTokenLogicStandard.new();
  		testWrbtc = await TestWrbtc.new();
  		doc = await TestToken.new("dollar on chain", "DOC", 18, web3.utils.toWei("20000", "ether"));
  
  		// Deploying sovrynProtocol
  		const sovrynproxy = await sovrynProtocol.new();
  		sovryn = await ISovryn.at(sovrynproxy.address);
  		await sovryn.replaceContract((await LoanClosingsBase.new()).address);
  		await sovryn.replaceContract((await LoanClosingsWith.new()).address);
  		await sovryn.replaceContract((await ProtocolSettings.new()).address);
  		await sovryn.replaceContract((await LoanSettings.new()).address);
  		await sovryn.replaceContract((await LoanMaintenance.new()).address);
  		await sovryn.replaceContract((await SwapsExternal.new()).address);
  		await sovryn.replaceContract((await LoanOpenings.new()).address);
  		await sovryn.replaceContract((await Affiliates.new()).address);
  
  		await sovryn.setSovrynProtocolAddress(sovrynproxy.address);
  
  		loanToken = await LoanToken.new(owner, loanTokenLogic.address, sovryn.address, testWrbtc.address);
  		await loanToken.initialize(doc.address, "SUSD", "SUSD");
  
  		loanTokenV2 = await LoanTokenLogicStandard.at(loanToken.address);
  		const loanTokenAddress = await loanToken.loanTokenAddress();
  		if (owner == (await sovryn.owner())) {
  			await sovryn.setLoanPool([loanTokenV2.address], [loanTokenAddress]);
  		}
  	});
  	beforeEach(async () => {
  		// initializing
  		const feeds = await PriceFeedsLocal.new(testWrbtc.address, sovryn.address);
  		await feeds.setRates(doc.address, testWrbtc.address, wei("0.01", "ether"));
  
  		const swaps = await SwapsImplLocal.new();
  		const sovrynSwapSimulator = await TestSovrynSwap.new(feeds.address);
  		await sovryn.setSovrynSwapContractRegistryAddress(sovrynSwapSimulator.address);
  
  		await sovryn.setSupportedTokens([doc.address, testWrbtc.address], [true, true]);
  
  		await sovryn.setPriceFeedContract(
  			feeds.address //priceFeeds
  		);
  		await sovryn.setSwapsImplContract(
  			swaps.address // swapsImpl
  		);
  		await sovryn.setFeesController(owner);
  		await sovryn.setWrbtcToken(testWrbtc.address);
  		{
  			/**
  			struct LoanParams {
  				bytes32 id; // id of loan params object
  				bool active; // if false, this object has been disabled by the owner and can't be used for future loans
  				address owner; // owner of this object
  				address loanToken; // the token being loaned
  				address collateralToken; // the required collateral token
  				uint256 minInitialMargin; // the minimum allowed initial margin
  				uint256 maintenanceMargin; // an unhealthy loan when current margin is at or below this value
  				uint256 maxLoanTerm; // the maximum term for new loans (0 means there's no max term)
  			}
  		*/
  		}
  		params = [
  			"0x0000000000000000000000000000000000000000000000000000000000000000", // bytes32 id; // id of loan params object
  			false, // bool active; // if false, this object has been disabled by the owner and can't be used for future loans
  			owner, // address owner; // owner of this object
  			doc.address, // address loanToken; // the token being loaned
  			testWrbtc.address, // address collateralToken; // the required collateral token
  			wei("20", "ether"), // uint256 minInitialMargin; // the minimum allowed initial margin
  			wei("15", "ether"), // uint256 maintenanceMargin; // an unhealthy loan when current margin is at or below this value
  			2419200, // uint256 maxLoanTerm; // the maximum term for new loans (0 means there's no max term)
  		];
  
  		await loanTokenV2.setupLoanParams([params], true);
  		await loanTokenV2.setupLoanParams([params], false);
  
  		// setting up interest rates
  		const baseRate = wei("1", "ether");
  		const rateMultiplier = wei("20.25", "ether");
  		const targetLevel = wei("80", "ether");
  		const kinkLevel = wei("90", "ether");
  		const maxScaleRate = wei("100", "ether");
  		await loanTokenV2.setDemandCurve(baseRate, rateMultiplier, baseRate, rateMultiplier, targetLevel, kinkLevel, maxScaleRate);
  
  		// GIVING SOME DOC tokens to loanToken so that we can borrow from loanToken
  		await doc.transfer(loanTokenV2.address, wei("500", "ether"));
  		await doc.approve(loanToken.address, web3.utils.toWei("20", "ether"));
  	});
  	it("Margin trading  with 3X leverage with DOC token and topUp position by 12rwBTC", async () => {
  		// setting up interest rates
  		//Giving some testRbtc to sovrynAddress (by minting some testRbtc),so  that it can open position in wRBTC.
  		await testWrbtc.mint(sovryn.address, wei("500", "ether"));
  
  		assert.equal(await sovryn.protocolAddress(), sovryn.address);
  
  		const leverageAmount = web3.utils.toWei("3", "ether");
  		const loanTokenSent = web3.utils.toWei("20", "ether");
  
  		await loanTokenV2.marginTrade(
  			constants.ZERO_BYTES32, // loanId  (0 for new loans)
  			leverageAmount, // leverageAmount
  			loanTokenSent, // loanTokenSent
  			0, // no collateral token sent
  			testWrbtc.address, // collateralTokenAddress
  			owner, //trader, // trader,
  			//referrer, // affiliates referrer
  			"0x", // loanDataBytes (only required with ether)
  			{ from: owner }
  		);
  		expect(await sovryn.getUserNotFirstTradeFlag(owner), "sovryn.getUserNotFirstTradeFlag(trader) should be true").to.be.true;
  	});
  });
  