SpartanDev: 09/08/21–15/08/21


We still need your support

It’s time to upgrade your tokens

feeBurn Update

Spartan Socials — Twitter

Top Impressions:

Top Engagement:

Top Community Mention:

SpartanSocials — Medium

SpartanSocials — Telegram

Contributor’s Focus

CodeArena Contest

  • COMPLETED — triage and prioritise the feedback submitted from the CodeArena wardens during the contest to prepare for the judges
  • IN PROGRESS — work through the post-contest tasks with the C4 judges & team for the eventual allocation of awards to security wardens
  • IN PROGRESS — communicate with security wardens to clarify/expand on feedback

SPARTA V2 (Token)

  • COMPLETED & ONGOING — Work with DEXs & aggregators to ensure up-to-date information on the new SPARTA token (retiring the previous contract address) (1inch, PancakeSwap etc)
  • COMPLETED & ONGOING — Work with token-tracking informational websites to ensure new token info is up-to-date (BSCscan, CoinGecko, CoinMarketCap etc)


  • COMPLETED — Sort and prioritise all CodeArena submissions into contract scopes along with tags based on ‘actionable’ or ‘discussion points’
  • IN PROGRESS — Implementing refinements to contracts to address C4 & contributor feedback since the C4 contest code-freeze
  • Deploy updated V2 contracts to BSC testnet for at least 1 week of community stress testing
  • Deploy completed V2 contracts to BSC mainnet
  • COMPLETED & ONGOING — Continue the code review process within the community


  • COMPLETED & ONGOING — Set up a reliable index of history scoped to contracts (use this for positions page etc)
  • IN PROGRESS — Use the new testnet subgraph to build a more lightweight positions page for V2

After Mainnet

  • Enable Bond allocations to replenish TVL into the V2 pools
  • March onwards with our original goals of building the decentralised, yield-generating synthetics protocol on Binance Smart Chain

GitHub Activity — SpartanSite


  • Converted static footer to a js component


  • Converted static header to a js component


  • Converted scrollUpButton to a component


  • Removed header, footer etc from all HTML pages and injected the components instead

GitHub Activity — SpartanContractsV2


  1. Weight logic changes to help reduce opportunity-size from manipulation:
  • Removed weight-related variables & mappings (we will no longer store weight as history and instead calculate it on the fly whenever it is being used)
  • Added mappings/variables to focus on staked/locked balances instead of weights
  • depositForMember()
  • calcBondedLP()
  • claimForMember()
  • getMemberDetails()
  • Removed ‘asset’ arg; this now gets the totalWeight of all relevant assets for the user
  • Added return of memberWeight & totalWeight
  • Removed getPool logic and instead get an array of relevant pools from the DAO
  • This function now simply loops the array handed back from DAO.listedBondPools() and gets a NET sum of the Utils.getPoolShareWeight() for both the member’s balance and the total held in the vault. This means that any manipulation of weight will scale all members of the same vault equally (in percentage terms; which is how the weight is utilized)


  1. Added ‘operational’ status to close off the functionality of a DAO in the event it is retired/upgraded:
  • Added ‘running’ variable (bool)
  • Added operational() modifier which requires ‘retire’ to be false
  • Yet to add in setter to be able to flip this true/false
  • Added ‘retire’ variable (bool)
  • Added isRunning() modifier which requires ‘running’ to be true
  • Set this as false in the constructor so that a newly deployed DAO will not have proposal functionality until the weight is distributed enough
  • Renamed to deposit()
  • Replaced ‘member’ with msg.sender
  • Removed forced harvest logic now that weight is calculated dynamically (threat is removed) however the issue of user’s time being reset by a deposit is now not fault-safe; this can be prevented however via the UI (check user’s available harvest and warn them away from depositing until they have harvested)
  • Simplified this to loop an array from the argument instead of a potentially unbounded list of bond assets
  • The UI knows exactly what assets to claim already; so it makes sense to shift the computation away from the EVM here
  • Changed member to msg.sender
  • newActionProposal()
  • newParamProposal()
  • newAddressProposal()
  • newGrantProposal()
  • withdraw()
  • removeVote()
  • Added input validation to prevent invalid proposals
  • Added a cap on the max grant size using the daoClaim basisPoints (10% by default)
  • Nested the event emission inside a conditional to resist event spamming
  • Added the removalFee logic for a small SPARTA fee on removal
  • Require the proposal is open
  • Require the proposal is not finalised
  • Added catch-all else statement to close a proposal that is invalid


  1. Weight logic changes to help reduce opportunity-size from manipulation:
  • Removed weight-related variables & mappings (we will no longer store weight as history and instead calculate it on the fly whenever it is being used)
  • Added mappings/variables to focus on staked/locked balances instead of weights
  • Removed increaseWeight() function
  • Removed decreaseWeight() function
  • getMemberLPWeight() created to handle looping the current DaoVault assets and getting a dynamic weight figure
  • memberWeight && totalWeight handed back as the return


  1. Added new pool initiation period which disables withdrawing liquidity until a time period has passed since the creation of the pool (defaults to 7 days)
  2. Factored the ‘oldRate’ calc to account for rounding (squared the numerator)
  3. removeForMember() — added require check to ensure withdrawals arent possible until the initiation period has passed (see #1)
  4. safetyCheck() — factored the calculations to account for wei rounding
  5. setInitiation() — added setter for the initiation period variable


  1. Calls the DAO for the protocol addresses (accounted for upgraded reserve contract via DAO):
  • Removed the address variables for DAO, ROUTER etc
  • Instead, call the source of truth (DAO) from the constant (BASE/SPARTA contract) and derive the current addresses from there


  1. Changes to dividends:
  • Removed most variables relating to the dividend calculation (maxTrades, normalAverageFee etc)
  • Removed most functions, setters and helpers relating to dividends
  • Gets the reserve balance
  • Gets the dividend max share of the reserve balance
  • Sends in a dividend that is equal to the size of the tradeFee if all conditions are valid
  • This creates a situation where the dividend (opportunity) is equal to the trade’s slip fee (cost of attack) if the attacker owns 100% of the pool (and if we ignore gas), and is more expensive than the opportunity in all other situations
  • This also obviously makes the dividend logic a lot cheaper as we don't need an array or a bunch of calculations & storage calls for every dividend-worthy swap


  1. Permissioned Synth.realise() to onlyDAO to potentially set up realise() to be only callable by the Liquidity providers that the function directly affects


  1. getPoolShareWeight() — hand in poolAddress rather than tokenAddress
  2. calcShare() — require total > 0 to avoid division by zero confusion
  3. calcLiquidityUnits() — added line-comments to help readability & added zero-division handling
  4. getSlipAdjustment() — added line-comments to help readability & added zero-division handling
  5. calcLiquidityHoldings() — added zero-division handling
  6. calcSwapOutput() — added zero-division handling
  7. calcSwapFee() — added zero-division handling
  8. calcSpotValueInBaseWithPool() — added zero-division handling
  9. calcSpotValueInTokenWithPool() — added zero-division handling
  10. calcSwapValueInBaseWithPool() — added zero-division handling


  1. Added vaultAssets array to handle ‘current’ vault-enabled assets
  2. addCuratedPool() — add new curated asset to vaultAssets array
  3. removeCuratedPool — remove curated asset from vaultAssets array
  4. _handleTransferIn() — simplified and removed return


  1. Removed DEPLOYER variable and assignment in constructor
  2. Removed onlyDAO()
  3. Removed purgeDeployer()


  1. Added purgeDeployer()
  2. setParams() — changed args to be more readable
  3. Changed deposit functions to use msg.sender instead of member
  4. Refactor weight changing logic into a new function changeWeight()
  5. harvestAll() — changed to be handed an array of assets to claim instead of looping the history (the UI knows exactly what assets to claim already)
  6. changeWeight() function added:
  • Requires the synth to be valid
  • Requires emissions to be on
  • Handle the balance/weight mappings updates
  • Require lockup period passed before harvesting
  • Added Pool.sync() here to prevent someone from using the internal tsf function to piggy-back a synthVault deposit on top of harvest() thereby bypassing the lockup period
  • Removed the Synth.realise() from here to partition the realise function to only be triggered by the DAO

Project Information

Official Links

Community Contribution

Engage with the community and contributors

Community Bounty Wallet




Incentivized liquidity and synthetic asset generation for Binance Smart Chain.

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Kotlin Is Changing

Get more done with value-added services from buzinessware

Writing clean and organized CSS

3, 2, 1, ig-listings

Basic Concepts of Flex Box

5 Ways to Prevent Accidentally Deleting Your CloudFormation Resources

How To Integrate Security into the DevOps Pipeline In AWS 2022?

How To Integrate Security into the DevOps Pipeline In AWS 2022?

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


Incentivized liquidity and synthetic asset generation for Binance Smart Chain.

More from Medium


DCN Staking Coming Soon: Win Tokens for Hodling

SpartanDev: 21FEB22–27FEB22

0x Project ZRX Token: Bullish, Bearish, Catfish?