diff --git a/CNAME b/CNAME index 8fd8671..da13e38 100644 --- a/CNAME +++ b/CNAME @@ -1 +1 @@ -switch.dfohub.com +www.unifihub.com diff --git a/README.md b/README.md index 5761c90..1fef6b7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,281 @@ # unifi -A DFO protocol powered DeFi set of tools built on top of Uniswap. +## Table of Contents +- [Table of Contents](#table-of-contents) +- [Decentralized Finance on top of Uniswap, doing fantastic things securely](#decentralized-finance-on-top-of-uniswap-doing-fantastic-thingssecurely) +- [Website: https://unifihub.com](#website-httpsunifihubcom) +- [Unified Stable Dollar](#unified-stabledollar) + - [Example:](#example) + - [Example:](#example-1) + - [Rebalancing](#rebalancing) + - [DFO Debit](#dfo-debit) + - [DFO Credit](#dfo-credit) + - [UniFi has a number of measures in place to ensure uSD's security.](#unifi-has-a-number-of-measures-in-place-to-ensure-usds-security) + - [Resilience, Decentralization and Independence](#resilience-decentralization-and-independence) + - [Allowed Stable Coins](#allowed-stablecoins) + - [APIs and Documentation](#apis-and-documentation) + - [Responsible DeFi Limits](#responsible-defilimits) +- [Craft and Initial Liquidity Offerings (ILOs)](#craft-and-initial-liquidity-offerings-ilos) + - [How Does It Work?](#how-does-it-work) + - [Programmable Liquidity Rules](#programmable-liquidity-rules) + - [Let's play out that aforementioned example.](#lets-play-out-that-aforementioned-example) + - [Initial Liquidity Offering (ILO)](#initial-liquidity-offeringilo) + - [Securing Initial Liquidity for AMMs With Fixed Inflation/Liquidity Staking](#securing-initial-liquidity-for-amms-with-fixed-inflationliquidity-staking) + - [Disarming Sniper Bots](#disarming-sniper-bots) + - [Securing Long Term Locked Investors](#securing-long-term-locked-investors) + - [How ILOs work:](#how-ilos-work) + - [Example](#example-2) +- [UniFi DFO Tax](#unifi-dfo-tax) +- [Releases](#releases) +- [The Bazar](#thebazar) + - [Listing](#listing) + - [Index Funds](#index-funds) + - [Programmable Equities](#programmable-equities) + - [Non-Fungible Tokens (NFTs)](#non-fungible-tokens-nfts) + - [Swappable ERC 1155 Release](#swappable-erc-1155-release) +- [UniFi Token Distribution](#unifi-token-distribution) + - [UniFi Fair Inflation](#unifi-fair-inflation) + - [UniFi Liquidity Staking](#unifi-liquidity-staking) +- [UniFi Earning System](#unifi-earningsystem) -## Built With +## Decentralized Finance on top of Uniswap, doing fantastic things securely +UniFi is a new Decentralized Flexible Organization (DFO) that researches and develops a responsible Decentralized Finance layer on top of Uniswap. A DFO protocol powered DeFi set of tools built on top of Uniswap -- dfohub -- Uniswap V2 Protocol -- Open Zeppelin ERC20 Token Contracts +## Website: https://unifihub.com + +## Unified Stable Dollar + +uSD is a stablecoin based on Uniswap Liquidity Pools Minted by the magic rainbow of Uniswap stablecoin pools, and backed by the power of the Unicorn, uSD is the most secure and resilient stablecoin on Ethereum - ever. The only way it could be destabilized is if the entire stablecoin industry crashed. +Independent from any off-chain issuer, it is fortified against every risk inherent to all other stablecoins, and free of the anxiety that pervades the industry. + +The protocol achieves this unprecedented feat by collateralizing other stablecoins. If any of them lose value or fail, it can simply rebalance itself to leverage the security of the others. And to account for excess due to fees earned by their pools, it can rebalance itself in another way. +The only way uSD can be destabilized is if the entire stablecoin industry collapses. + +uSD is backed by a selection of Uniswap's (whitelisted) stablecoin liquidity pools.Anyone can mint it by adding these stablecoins to those pools. + +### Example: + +Mint 2x uSD by adding 1x Stablecoin A and 1x Stablecoin B And by burning uSD, anyone can receive these stablecoins from those pools. + +### Example: + +Burn 2x uSD and receive 1x Stablecoin A and 1x Stablecoin C + +### Rebalancing + +Sometimes, collateralization is not enough, and uSD must rebalance in one of two ways. + +#### DFO Debit + +When a stablecoin loses value, the Uniswap Tier pools rebalance to an uneven disparity (≠ 50/50). + +If the stablecoin totally fails, the other stablecoins effectively pump in correlation.DFO Debit resolves this issue on-chain by rebalancing uSD, creating debt which the UniFi DFO then pays off by minting UniFi. Let’s look at how this plays out, step by step: + +1 - A stablecoin collateralized by uSD loses value or fails altogether. + +2 - $UniFi holders vote to remove the tiers containing the failed stablecoin from the whitelist.The uSD supply becomes grater than the supply of the collateralized pooled stablecoins. + +3 - To restore 1:1 equilibrium, anyone holding uSD can burn it to receive new UniFi, minted at a 20% discount of the uSD/UniFi Uniswap pool mid-price ratio. + +The goal of $UniFi holders, which aligns with their self-interest, is to ensure uSD’s security. Thus there is an economic disincentive to whitelist insecure stablecoins. + +#### DFO Credit + +As established, uSD is backed by Uniswap stablecoin pools liquidity. + +This raises an issue; Uniswap pools earn 0.3% of trading fees. This could destabilize uSD by creating an excess of collateralized stablecoins in the pools.DFO Credit, the second rebalancing function of the UniFi DFO, resolves this by removing that excess from the pools and sending it in the DFO wallet managed by $UniFi holders. + +This is a long term economic incentive for the UniFi DFO to grow and invest credit in R&D. + +### UniFi has a number of measures in place to ensure uSD's security. + + -  uSD pool collateral is locked. Stored in an external smart contract, it can't be touched even by the UniFi DFO, precluding voter fraud by bad actors. + -  In the case of any bug or update, $UniFi holders can vote to pause the uSD smart contract. This prevents minting of new uSD or rebalancing of uSD, but holders will still be able to redeem it for the pooled stable coins, and thus revoke the collateral. + -  Even if the uSD protocol fails, and even if the UniFi DFO votes to update uSD to an undesirable new version, uSD holders will still be able to interact with the old smart contract - until all collateral is revoked - as well as the new one. + +### Resilience, Decentralization and Independence + +uSD is indeed the most resilient and secure stablecoin in the industry. By taking advantage to use Decentralized Finance on the top of Uniswap, a security layer with a decentralized core, it frees holders from dependence on censorship or centralized manipulation by states and stablecoin issuers, and resolves all risks that come with trusting the big stablecoin companies, like MakerDAO, Coinbase, etc. +It is backed by a Decentralized Flexible Organization. $UniFi holders on the Ethereum network have 100% control of the code and Credit/Debit of the protocol. Nobody can stop or censor the UniFi-uSD protocol; for the first time, the Ethereum network doesn't have to choose between stability and independence in a stablecoin; it can have both. + +### Allowed Stable Coins + +The allowed stablecoins to mint and burn uSD with are: + +DAI 0x6b175474e89094c44da98b954eedeac495271d0f +USDC 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 +GSDC 0x056fd409e1d7a124bd7017459dfea2f387b6d5cd +BUSD 0x4fabb145d64652a948d72533023f6e7a623c7c53 +TUSD 0x0000000000085d4780b73119b644ae5ecd22b376 +PAX 0x8e870d67f660d95d5be530380d0ec0bd388289e1 + +### APIs and Documentation + +To build on top of uSD and to interact with the dApp, you can find all of the documentation and APIs here: Documentation + +### Responsible DeFi Limits + +Because we take a Responsible DeFi Approach, UniFi uSD minting is limited in its early stages: + +- 500,000 uSD mintable for the first month (until block n 10941929) +- 2,000,000 uSD mintable for the first two months (until block n 11141929) +- 5,000,000 uSD mintable for the first three months (until block n 11341929) +- 10,000,000 uSD mintable for the first four months (until block n 11541929) +- 20,000,000 uSD mintable for the first five months (until block n 11741929) + +## Craft and Initial Liquidity Offerings (ILOs) + +Craft makes it possible to provide liquidity that is programmable with advanced rules. Using Unicorn magic, pools can balance tokens diversely, and with unprecedented security. + +Programmable liquidity is an exciting new feature in AMMs (Automated Market Makers). However, if not applied correctly, it can actually be a security hole for bugs, due to math complexities (as we saw with Balancer recently). + +UniFi Crafting resolves this by offering programmable liquidity, but with the Uniswap protocol as a base layer, taking advantage of its secure and decentralized core. This also helps liquidity providers customize their investments, and empowers new applications on top of Uniswap. + +### How Does It Work? + +The Uniswap protocol allows for liquidity pools composed of 50:50 asset ratios. This is usually the most secure setup for an AMM, but disincentivizes liquidity provision by incurring impermanent losses. Crafting resolves this, and opens up novel financial use cases for Uniswap pools. It is a fancy new way to build liquidity together, without needing to trust and know each other. + +Anyone can create a Craft order, customize the liquidity setup and deploy it by contributing initial liquidity. Others can then contribute the rest of the liquidity required to pool the order on Uniswap. Later, after the predetermined block, any of the participants can trigger removal of the liquidity. It is then distributed to all participants based on the predetermined rules. + +### Programmable Liquidity Rules + +With Crafting, Uniswap liquidity providers can program a liquidity order by customizing the following: + +- Tier: The Uniswap tier to which the liquidity will be added +- Waiting Length: The max time (in blocks) the order can remain available while the required liquidity is waiting to be filled. +- Min Block Length: The time (in blocks) for which the liquidity will be locked. If 0, any participant can trigger the removal of liquidity anytime. +- Liquidity Ratio: The ratio of liquidity, e.g. 10% DAI - 90% ETH or 0% DAI - 100 ETH. Once deployed by the creator, others can add the required liquidity. If the creator sets the ratio at 10% DAI - 90% ETH, the others can add the rest at 90% DAI - 10% ETH. +- Liquidity Exit/Discount: An advanced feature for orders that allows for the creation of a different ratio or even a discount for the exit. + +#### Let's play out that aforementioned example. + +Person A creates an order for USDC - DAI, with a min block length of 543055 Blocks and a ratio of 10% DAI - 90% USDC. He adds 100 DAI and 900 USDC, and also decides to set the exit liquidity at 30% DAI and 70% USDC (read on to see exactly how exit liquidity works). + +B fills part of the remaining required liquidity (at a ratio of 90% DAI and 10% USDC) with 500 DAI and 50 USDC. + +C fills part of the remaining required liquidity (at a ratio of 90% DAI and 10% USDC) with 100 DAI and 10 USDC. + +D fills the rest of the required liquidity (at a ratio of 90% DAI and 10% USDC) with 300 DAI and 30 USDC. + +By adding the final remaining required liquidity, D has triggered Uniswap's Add Liquidity order … + +The total Uniswap liquidity pooled by A,B,C and D is 1,000 DAI and 1,000 USDC. + +After 543055 blocks, the liquidity pool has earned 1,000 USDC and 1,000 DAI in Uniswap trading fees, bringing the total to 2,000 DAI and 2,000 USDC. + +… B then triggers the removal action, and based on the fixed predetermined rules, the providers receive the following: + +A receives 600 DAI and 1,400 USDC (at the Exit Ratio of 30% DAI and 70% USDC). + +Based on how much they individually contributed, B, C and D receive their respective proportion of 1,400 DAI and 600 USDC (at the Exit Ratio of 70% DAI and 30% USDC). + +### Initial Liquidity Offering (ILO) + +ILOs are a way for Ethereum-based startups to configure "Crafting" - i.e, Programmable Liquidity - rules to secure long term funding by providing Uniswap liquidity. + +ILOs are helpful for three specific reasons: + +#### Securing Initial Liquidity for AMMs With Fixed Inflation/Liquidity Staking + +Providers can offer liquidity with fixed inflation without dumping on new holders. They also help new investors reduce slippage and become holders with a large amount of capital. + +#### Disarming Sniper Bots + +Sniper Bots track new low liquidity Uniswap pools for sizable capital before liquidity even comes in, making it (until now) impossible for startups to offer liquidity with low collateral. + +#### Securing Long Term Locked Investors + +Investors lock their funds for the long run. + +#### How ILOs work: + +Before distributing their tokens, startups can set crafting orders with fixed pre-values, adding the token and requesting the collateral required to fill the order. Investors provide that collateral, and if the startup chooses, investors get an Exit/Discount to mitigate the high risk. + +##### Example + +The token creator sets a Crafting order with low liquidity, e.g. 1,000,000 of the token and 1 ETH, with a 90% - 10% ratio, or even 1,000,000 of token and 0 ETH, with a 100% - 0% ratio (adding a pre-value of the token, if the liquidity pool is not open yet) for one year. Setting the Liquidity Exit/Discount 10%/20%, investors will receive at the end of the order 90%/80%. + +In this case, investors invest their own Ethereum for a new token that is not already tradable. This entails a high level or risk, and so they are compensated by receiving a more significant portion of the liquidity at the end of the year; in this case, from 50% added to 170% received. + +ILOs enable new Ethereum fundraising rules that solve liquidity issues in early stages, while also helping legitimate projects set Fixed Inflation. This empowers projects and investors in the long run.UniFi DFO Tax: + +## UniFi DFO Tax + +The UniFi DFO earns via the Crafting function; 0.1% of the total Uniswap pool tokens in a Craft order is taxed and paid directly when a participant calls the remove function. + +## Releases + +The release Of Crafting and ILOs is expected for early October 2020. + +## The Bazar + +Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities and Token Index Funds (and soon NFTs, including ERC1155s, thanks to ethArt V2) can now be swapped on the new Bazar DEX. + +The UniFi Bazar unleashes the true potential of Decentralized Finance on the top of Uniswap, by enabling Ethereans to trade these more easily than ever before. + +### Listing + +#### Index Funds + +Previously, any ERC20 Uniswap V2 pool token could be traded on Uniswap. But Index Funds - backed by multiple ERC20 tokens - could not. Until now. + +On the Bazar, Ethereans can freely swap and track crypto Index Funds. + +#### Programmable Equities + +Programmable equities are a new asset class in crypto. They are the ERC20 voting tokens of Decentralized Flexible Organizations (DFOs). Holders have 100% ownership of the protocol; there is no opportunity for external manipulation. + +On the Bazar, all programmable equities can be listed and traded on Uniswap. + +#### Non-Fungible Tokens (NFTs) + +ERC1155 NFTs are tokens with metadata, but at the same time have a supply. The reason they haven't been tradable in AMMs before is due to their 'transfer' function. They use the 'SafeTransferFrom' method, instead of the ERC20 methods, 'Transfer' and 'TransferFrom.' Also, they don't have decimals; they're transferred using ID and Amount. + +ethArt V2 will be released in November, and the Bazar will be able to synthesise ERC1155 tokens with ERC20s (as WETH with ETH) in the background, fundamentally reshaping the NFT market by allowing Ethereans to trade ERC1155 tokens for the first time. + +#### Swappable ERC 1155 Release + +The release of ethArt V2 and swappable NFTs is scheduled for late November.  + +## UniFi Token Distribution + +The total supply of $UniFi is 88,888,888, which is initially distributed and Locked as follows: + +- 36% (32,042,000) are locked in the NERV Wallet [0x25756f9C2cCeaCd787260b001F224159aB9fB97A] This is the DFOhub Operation' DFO wallet, funded by Fair Inflation. +- 40% (35,900,000) are locked in the UniFI's DFO wallet [0x2578aA454b29C15c8eEF62C972Ee1ff57CD99DEf]. This pays out the liquidity staking rewards. The active reward staking contract is [0xb266252Fd70D253b4330151A96694d35e94b846c] +- 16% (14,333,333) are locked in the DFOhub wallet (owned by $buidl holders) [0x5D40c724ba3e7Ffa6a91db223368977C522BdACD] + +### UniFi Fair Inflation + +A sustainable economic model for DFO-based startups to maintain value and fund operations | UniFi version + +The original whitepaper of the first fair inflation mechanism was for buidl ((https://github.com/b-u-i-d-l/fair-inflation-v2)) +UniFi's fair inflation will inflate the supply by 2% (1,788,500 $UniFi) over the first year via NERV (The DFOhub Team Operations' DFO) + +Inflation events will occur once a day (every 6,300 ETH Blocks) across three Uniswap pairs, for a total of 4,900 $UniFi each event: + +- Uniswap V2 $ETH/$UniFi (2695 $UniFi every day) - 55% +- Uniswap V2 $USDC/$UniFi (1470 $UniFi every day) - 30% +- Uniswap V2 $BUIDL/$UniFi (735 $UniFi every day) - 15% + +All functionalities related to this R&D will become available for every DFO as Optional Basic Functionalities, to accelerate the exploration of Programmable Equity R&D. + +### UniFi Liquidity Staking + +$UniFi liquidity staking is available here: https://dapp.dfohub.com/?staking=0xb266252Fd70D253b4330151A96694d35e94b846c + +The UniFi Liquidity Staking Mechanism is designed to reward those who lock up Uniswap V2 liquidity for the long term. + +Staking will inflate the supply over the first year (if every tier is completely filled) by 918,000 $UniFi (1% of the supply). + +The Five Year tier was filled by the team in an early test, and we won't touch the rewards for three years. When they are unlocked and redeemed, 50% of the UniFi will be sent to the UniFi wallet and 50% to the NERV operations wallet. + +## UniFi Earning System + +The UniFi DFO earn from: + +- The uSD positive rebalance (the trading fees of Uniswap collateralized stablecoins) +- The 0.1% in Uniswap Pool Tokens taxed by crafting Programmable Liquidity + +As an on-chain company, UniFi's value will be backed by these earnings, and by the core of Flexible Organizations, totally ruled in code and assets by tokens, without any chance of external manipulation. diff --git a/assets/css/style.css b/assets/css/style.css index 0388303..b89c965 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -1,6 +1,6 @@ html {margin: 0; background-color: #2b2622;} h1,h4,h3, h5,h6,h2 {margin-block-end: 0;margin-block-start: 0;} -body {width: 100%; position: relative; margin: 0; font-family: "Myriad Pro";} +body {width: 100%; position: relative; margin: 0;} ol,ul, li {margin-block-start: 0; margin-block-end: 0; list-style-type: none; padding-inline-start:0;} p {display: inline-block;margin-block-start: 0px;margin-block-end: 0px;margin-inline-start: 0px;margin-inline-end: 0px;} h1 {font-size: 30px;} @@ -23,6 +23,7 @@ section, article, label {display: inline-block;} .expMoreandMore {width: 100%; text-align: center; padding: 50px 0;} .expMoreandMore h5 {font-size: 25px; color: #c7ac97;} .expMoreandMore h5 img {width: 40px; height: 40px; vertical-align: middle;} +.unifiAll {min-height: 100%;} .loaderRegular {margin: 30px auto; width: 100px; height: 100px; padding: 30px; border-radius: 8px;} .loaderMini {width: 30px; height: 30px; vertical-align: middle; margin: 0 10px; display: inline-block;} @@ -60,20 +61,37 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .unifiDapp {position: relative;} .unifiDapp .MenuAll {width: 100%; position: fixed; top: 0; left: 0;} .unifiDapp .MenuAll .connectOpener, .unifiDapp .MenuAll .menuOpener {padding: 6px 10px; border-radius: 8px; margin-top: 10px;text-decoration: none;} -.unifiDapp .MenuAll .maghetto {width: 40px; height: 40px; float: left;margin: 5px 10px 0 20px;} +.unifiDapp .MenuAll .maghetto {width: 30px; height: 30px; float: left;margin: 5px 10px 0 20px;} .unifiDapp .MenuAll .maghetto img {width: 100%; height: 100%;} .unifiDapp .MenuAll .menuOpener {float: left; margin-left: 20px;} -.unifiDapp .MenuAll .menuOpener, .unifiDapp .MenuAll .connectOpener span {font-size: 18px; font-weight: bold;} +.unifiDapp .MenuAll .menuOpener, .unifiDapp .MenuAll .connectOpener span {font-size: 12px; font-weight: bold;} .unifiDapp .MenuAll .connectOpener {float: right; margin-right: 20px; text-decoration: none;} -.unifiDapp .MenuAll .connectOpener img {width: 25px; height: 25px; vertical-align: middle;} -.unifiDapp .MenuAll .connectOpener span {font-size: 18px; vertical-align: middle;} -.unifiDapp .MenuOpen {text-align: left; position: absolute; left: 90px; top: 50px; z-index: 99999999999999;} -.unifiDapp .MenuOpen .coverMenu {margin: 0;z-index: 99999999999999;} +.unifiDapp .MenuAll .connectOpener img {width: 10px; height: 10px; vertical-align: middle;} +.unifiDapp .MenuAll .connectOpener span {font-size: 12px; vertical-align: middle;} +.unifiDapp .MenuOpen {text-align: left; position: absolute; left: 10px; top: 50px; z-index: 99999999999999;} +.unifiDapp .MenuOpen .coverMenu {margin: 0;z-index: 99999999999999;outline: -webkit-focus-ring-color auto 0px;} +.ethereumWalletProvider {text-align: left; position: absolute; right: 20px; top: 0px; z-index: 99999999999999;} + .UniBox, .UniSideBox {position: relative;max-width: 250px;width: 100%; opacity: 1;padding: 30px 1rem; margin: 50px 10px 50px 10px;vertical-align: top;} .UniStableManage {width: 25px; height: 25px;vertical-align: middle; margin: 7px;} .UniActiveQuantityTier, .UniDisactiveQuantityTier {display: inline-block; margin: 5px auto;} .UniTierQuantity h6 {font-size: 15px; margin: 6px auto;} -.StableCoinTitle, .grimoireWelcome {width: 100%; margin-top: 100px; text-align: center;} +.StableCoinTitle, .grimoireWelcome {width: 100%; margin-top: 30px; text-align: center;position: initial;z-index: 1;} +.grimoireBoxAll {width: 100%; margin-top: 25px; text-align: center;} +.grimoireBox {width: 95%; margin-bottom: 18px; text-align: center;} +.grimoireIndex {width: 95%; margin-left: 4%; text-align: left;} +.grimoireIndex h2 {font-size: 20px; margin-bottom: 20px; margin-top: 20px;} +.grimoireIndex a {width: 100%; padding: 10px 0; display: inline-block; font-size: 14px; vertical-align: middle;} +.grimoireIndex a img {width: 20px;height: 20px; margin-right: 6px; vertical-align: middle;} +.grimoireArticle {width: 90%; padding: 4%; text-align: left;} +.grimoireArticle h2 {font-size: 30px; margin-bottom: 25px;} +.grimoireArticle p {font-size: 15px; line-height: 1.4; width: 100%; display: inline-block; margin-bottom: 15px;} +.grimoireArticle h6 {font-size: 19px; width: 100%; display: inline-block; margin-bottom: 20px; font-weight: normal;margin-top: 10px;} +.grimoireArticle h4 {font-size: 21px; width: 100%; display: inline-block; margin-bottom: 15px; font-weight: bold;} +.grimoireArticle ol {width: 100%; display: inline-block; text-align: right;} +.grimoireArticle li {width: 95%; text-align: left; display: inline-block; font-size: 15px;line-height: 1.3; margin: 10px auto;} + + .StableCoinTitle .StableCoinTitleIntern, .grimoireWelcome .grimoireWelcomeIntern {display: none;} .StableCoinTitle h2, .grimoireWelcome h2 {font-size: 25px; margin: 10px 0; vertical-align: middle;text-align: left;} .StableCoinTitle h6, .grimoireWelcome h6 {font-size: 15px; text-align: left; line-height: 1.4; font-weight: normal;} @@ -107,7 +125,7 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .RebalanceEmergency label span {display: inline-block; margin: 0 5px; font-size: 15px;} .RebalanceEmergencyRew {width: 100%; display: inline-block;} .coverConnectMenu:focus {border: none; outline: -webkit-focus-ring-color auto 0px;} - +.Boh {position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; z-index: 5;} .UniTitle select, .UniTierQuantity label input {padding: 2px 5px; font-size: 15px; font-weight: bold; margin: 7px; vertical-align: middle;} .UniTitle p {font-size: 17px;margin: 7px; font-weight: normal;} @@ -120,13 +138,105 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .UniTierQuantity label img {width: 20px; height: 20px; margin: 0 5px; vertical-align: middle; display: inline-block;} .UniTierQuantity label input, .RebalanceEmergency label input {width: 130px; display: inline-block; height: 30px;} +.CallToGrim {position: fixed; top: 10px; left: 190px; width: 35px; height: 35px;} +.CallToGrim {display: none;} +.CallToGrim a {width: 35px; height: 35px; display: inline-block; text-align: center; border-radius: 10px;} +.CallToGrim a img {width: 30px; height: 30px; display: inline-block; vertical-align: center;} +.BoomerModeToggler {width: 20px; height: 20px; display: inline-block; text-align: center; border-radius: 10px; position: fixed; bottom: 10px; right: 0px; text-decoration: none;line-height: 2; font-size: 12px;} +.explainer .BoomerModeToggler {display: none;} +.BazTokenSelector {width: 100%; display: inline-block; margin: 10px auto; text-align: center;} +.BazTokenSelector a {padding: 10px 20px; text-decoration: none; font-weight: bold; display: inline-block; margin: 5px; border-radius: 6px;} +.BazSelectorContainer {position: fixed; top: 20%; left: 5%; width: 90%; overflow-y: scroll;overflow-x: hidden; height: 60%; margin: auto; z-index: 10; border-radius: 10px;} +.BazSelectorContainerClose {position: fixed; border-radius: 50%; width: 30px; height: 30px; top: 20px; left: 5px;top: 10%;left: 48%;} +.BazSelectorContainerClose a {font-size: 18px; padding: 0;} +.BazSelectorContainerMenu {display: inline-block; width: 100%;} +.BazSelectorContainerMenuintern {width: 100%;} +.BazSelectorContainerMenu li {width: 33.3%; display: inline-block; height: 32px;} +.BazSelectorContainerMenu li a {padding: 8px 0; width: 100%; margin: 0; font-size: 13px; font-weight: bold;} +.BazSelectorContainerObjects {width: 95%; display: inline-block; margin-top: 20px; text-align: left;} +.BazSelectorContainerObjects li {display: inline-block; width: 110px; margin: 10px;word-wrap: break-word;} +.BazSelectorContainerObjects li a {font-size: 13px; font-weight: normal; padding: 3px 6px; margin: 0; border-radius: 0; display: inline-block;} +.BazSelectorContainerObjects li a img {width: 20px; height: 20px; vertical-align: middle;} +.BazSelectorContainerObjects li a p {display: inline;} +.BazzPreDescDisabled {display: none;} +.BazPrice {width: 100%; text-align: center;display: inline-block; font-weight: bold;} +.StableITBTNDisabled, .StableITBTNFDisabled {display: none;} +.StableITBTNActive, .StableITBTNFActive {display: inline-block;} +.StableITBTNFActive {font-size: 13px; padding: 5px 9px; margin-top: 5px;} +.ArrivaUniswap {position: fixed; width: 80%; height: 80%; overflow: hidden; z-index: 10;left: 10%;top: 10%;border: none;border-radius: 35px;} +.ArrivaUniswap img {width: 30%; position: absolute; left: 35%; top: 150px;} +.ArrivaUniswapQuelloVero iframe {position: fixed;width: 90%;height: 80%;overflow: hidden;left: 5%;top: 10%;z-index: 9;border: none;border-radius: 35px;} +.SeneVaUniswap {position: fixed; top: 10px; left: 70%; border-radius: 50%; width: 30px; height: 30px; line-height: 2; font: 12px; font-weight: bold; text-decoration: none;} +.grimoire .connectOpener, .swapBazar .connectOpener{display: none;} +.grimoire .BoomerModeToggler, .swapBazar .BoomerModeToggler {right: 15px;} +.grimoire .grimoireWelcome {display: inline-block; margin-top: 60px; width: 90%;} +.grimoire .grimoireWelcomeintern {display: inline-block;border-radius: 30px; padding: 15px 0;} +.grimoire .grimoireWelcomeintern img {display: none;} +.grimoire .grimoireWelcomeintern article {width: 80%;display: inline-block;} +.grimoire .grimoireWelcomeintern h2 {font-size: 20px;} +.grimoire .grimoireWelcomeintern h6 {font-size: 13px;} +.grimoire .grimoireArticle {word-wrap: break-word;} +.grimUnifi, .grimBazar, .grimCrafting, .grimuSD {max-width: 100%;} +.coverMenu {margin: 50px auto 50px auto; width: 90%; border-radius: 8px; text-align: left; padding: 8px 5px;} +.coverMenu li {width: 200; display: inline-block; position: relative; margin-left: 25px;} +.coverMenu li a {width: 100%; display: inline-block; padding: 5px 5px; text-decoration: none;} +.coverMenu li a img {width: 35px; height: 35px; margin: 0 7px; vertical-align: middle;} +.coverMenu li a span {font-size: 16px; font-weight: bolder; vertical-align: middle;} +.coverMenu li .menuArrow {display: none;} +.coverMenu li:hover .menuArrow {width: 20px; height: 20px; position: absolute; left: -15px; top: 15px; display: block;} +.coverMenu .menuArrow img {width: 20px; height: 20px;} -.Boomer .UniBox {background: rgb(33, 36, 41); box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px; border-radius: 30px; color: #f1f1f1;} -.RPG .UniBox {position: initial;background: rgb(33, 36, 41); border-radius: 20px; color: rgb(195, 197, 203);box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;width: 100%;} +.Boomer .UniBox, .Boomer .grimoireBox {position: initial;background: rgb(255, 255, 255); box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px; border-radius: 30px; color: #000000;} +.Boomer .UniSideBox {border-radius: 20px; color: #000000; width: 100%; background-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer {background: linear-gradient(29deg, rgba(255,255,255,1) 0%, rgba(228,228,228,1) 66%);font-family: "Inter var", sans-serif;} +.Boomer > .explainer {background: linear-gradient(29deg, rgba(80,80,80,1) 0%, rgba(46,46,46,1) 66%);font-family: "Myriad Pro";} +.Boomer .UniTitle select, .Boomer .UniActiveQuantityTier input, .Boomer .UniDisactiveQuantityTier input, .Boomer .RebalanceEmergency label input {background-color: #e7e7e7; color: #000000; border: 5px solid #e7e7e7; border-radius: 5px;} +.Boomer .UniTitle {color: #000000;} +.Boomer .menuOpener, .Boomer .connectOpener {background-color: #bab9b9; color: #000000;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .unifiDapp .MenuOpen .coverMenu {background-color: #bab9b9; border-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .StableCoinTitleIntern, .Boomer .grimoireWelcomeIntern {background-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .StableCoinTitle h2, .Boomer .grimoireWelcome h2 {color: #000000;} +.Boomer .StableCoinTitle h6, .Boomer .grimoireWelcome h6 {color: #000000;} +.Boomer .StableCoinTitle h6 a, .Boomer .grimoireWelcome h6 a {color: #000000;} +.Boomer .UniSideBox .SideStandard h6 a {color: #000000;} +.Boomer .UniSideBox .SideStableList li span {color: #000000;} +.Boomer .UniSideBox .SideHealth aside {background-color: #128b03; border:none;} +.Boomer .loaderRegular {background-color: #e3d2c2;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .Disclamerone a {color: #000000; text-decoration: underline;} +.Boomer .UniActiveQuantityTier h6, .Boomer .UniDisactiveQuantityTier h6 {color: #000000;} +.Boomer .UniActiveQuantityTier h6 a, .Boomer .UniDisactiveQuantityTier h6 a {background-color: #000000; color: #ffffff; border-radius: 5px; margin-right: 5px;} +.Boomer .coverConnectMenu .ethereumWalletProvider {background-color: #bab9b9; border-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px; color: #000000;} +.Boomer .ethereumWalletProvider a {color: #000000;} +.Boomer .grimoireIndex h2 {color: #000000;} +.Boomer .grimoireIndex a {color: #000000;} +.Boomer .coverMenu li a span {color: #000000;} +.Boomer > .explainer .coverMenu li a span {text-shadow: 2px 2px 2px #5d5e60;color: #bab9b9;} +.Boomer .CallToGrim a {background-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .maghetto {-webkit-filter: grayscale(100%); filter: grayscale(100%);} +.Boomer .BoomerModeToggler {background-color: #bab9b9;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.Boomer .grimoireArticle a {color: #000000; font-weight: bold;} +.Boomer .BazTokenSelector a {background-color: #bab9b9; color: #000000;} +.Boomer .BazSelectorContainer {background-color: #ffffff; color: #444444;} +.Boomer .BazSelectorContainer:focus {border: none;} +.Boomer .BazSelectorContainerMenu {background-color: #bab9b9;} +.Boomer .BazSelectorContainerClose {background-color: #bab9b9;} +.Boomer .BazSelectorContainerMenu .selected {background-color: #ffffff;} +.Boomer .BazSelectorContainerMenu .selected a {color: #000000;} +.Boomer .BazSelectorContainerMenu a {background-color: transparent;} +.Boomer .Boh {background-color: #000000eb;} +.Boomer .BazSelectorContainerObjects li a {background-color: transparent; color: #000000; font-weight: bold;} +.Boomer .ActiveDesc {color:#000000;display: inline-block;} +.Boomer .StableITBTNActive {background-color: #b030df;} +.Boomer .StableITBTNFActive {background-color: #5549c9;} +.Boomer .ArrivaUniswap {background-color: #ffffff;} +.Boomer .SeneVaUniswap {background-color: #ffffff; color: #000000;} + + +.RPG .UniBox, .RPG .grimoireBox {position: initial;background: rgb(33, 36, 41); border-radius: 20px; color: rgb(195, 197, 203);box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} .RPG .UniSideBox {border-radius: 20px; color: #bab9b9; width: 100%; background-color: #2b2622;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} -.RPG body {background: linear-gradient(29deg, rgba(80,80,80,1) 0%, rgba(46,46,46,1) 66%);} -.RPG .UniTitle select, .RPG .UniActiveQuantityTier input, .RPG .UniDisactiveQuantityTier input, .RebalanceEmergency label input {background-color: #000000; color: #f1f1f1; border: 5px solid #000000; border-radius: 5px;} -.RPG .UniTitle {color: rgb(195, 197, 203);} +.RPG {background: linear-gradient(29deg, rgba(80,80,80,1) 0%, rgba(46,46,46,1) 66%);font-family: "Myriad Pro";} +.RPG .UniTitle select, .RPG .UniActiveQuantityTier input, .RPG .UniDisactiveQuantityTier input, .RPG .RebalanceEmergency label input {background-color: #000000; color: #f1f1f1; border: 5px solid #000000; border-radius: 5px;} +.RPG .UniTitle {color: #bab9b9;} .RPG .menuOpener, .RPG .connectOpener {background-color: #c7ac97; color: #444444;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} .RPG .unifiDapp .MenuOpen .coverMenu {background-color: #2b2622; border-color: #2b2622;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} .RPG .StableCoinTitleIntern, .RPG .grimoireWelcomeIntern {background-color: #2b2622;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} @@ -141,8 +251,55 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .RPG .UniActiveQuantityTier h6, .RPG .UniDisactiveQuantityTier h6 {color: #adadad;} .RPG .UniActiveQuantityTier h6 a, .RPG .UniDisactiveQuantityTier h6 a {background-color: #000000; color: #ffffff; border-radius: 5px; margin-right: 5px;} .RPG .coverConnectMenu .ethereumWalletProvider {background-color: #2b2622; border-color: #2b2622;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.RPG .ethereumWalletProvider a {color: #bab9b9;} +.RPG .grimoireIndex h2 {text-shadow:2px 2px 2px #5d5e60; color: #bab9b9;} +.RPG .grimoireIndex a {text-shadow:2px 2px 2px #5d5e60; color: #bab9b9;} +.RPG .coverMenu li a span {text-shadow: 2px 2px 2px #5d5e60;color: #bab9b9;} +.RPG .CallToGrim a {background-color: #c7ac97;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.RPG .BoomerModeToggler {background-color: #c7ac97;box-shadow: rgba(0, 0, 0, 0.01) 0px 0px 1px, rgba(0, 0, 0, 0.04) 0px 4px 8px, rgba(0, 0, 0, 0.04) 0px 16px 24px, rgba(0, 0, 0, 0.01) 0px 24px 32px;} +.RPG .grimoireArticle a {color: #c7ac97; font-weight: bold;} +.RPG .BazTokenSelector a {background-color: #000000; color: #ffffff;} +.RPG .BazSelectorContainer {background-color: rgb(33, 36, 41); color: #444444;} +.RPG .BazSelectorContainerMenu {background-color: #000000;} +.RPG .BazSelectorContainerClose {background-color: #c7ac97;} +.RPG .BazSelectorContainerMenu .selected {background-color: #c7ac97;} +.RPG .BazSelectorContainerMenu .selected a {color: #000000;} +.RPG .BazSelectorContainerMenu a {background-color: transparent;} +.RPG .Boh {background-color: #c7ac97d6;} +.RPG .BazSelectorContainerObjects li a {background-color: transparent; color: #ffffff; font-weight: bold;} +.RPG .BazSelectorContainerMenu li a {font-size: 14px;} +.RPG .BazSelectorContainerClose a {background-color: transparent; color: #000000;} +.RPG .ActiveDesc {color:#5d5e60; display: inline-block;} +.RPG .StableITBTNActive {background-color: #5549c9;} +.RPG .StableITBTNFActive {background-color: #c7ac97; color: #1a1a1a;} +.RPG .ArrivaUniswap {background-color: #e3d2c2;} +.RPG .SeneVaUniswap {background-color: #e3d2c2; color: #000000;} @media only screen and (min-width: 640px) { + .grimoire .grimoireWelcomeintern img {display: inline-block;} + .BazTokenSelector {width: 100%; display: inline-block; margin: 10px auto; text-align: center;} + .BazTokenSelector a {padding: 10px 20px; text-decoration: none; font-weight: bold; display: inline-block; margin: 5px; border-radius: 6px;} + .BazSelectorContainer {position: fixed; top: 20%; left: 50%; width: 90%; overflow-y: scroll;overflow-x: hidden; height: 60%; margin: auto; z-index: 10; border-radius: 10px;} + .BazSelectorContainerClose {position: fixed; border-radius: 50%; width: 40px; height: 40px; top: 70px; left: 5px;top: 14%;left: 48%;} + .BazSelectorContainerClose a {font-size: 25px; padding: 0;} + .BazSelectorContainerMenu {display: inline-block; width: 100%;} + .BazSelectorContainerMenuintern {width: 100%;} + .BazSelectorContainerMenu li {width: 33.3%; display: inline-block; height: 32px;} + .BazSelectorContainerMenu li a {padding: 8px 0; width: 100%; margin: 0; font-size: 13px; font-weight: bold;} + .BazSelectorContainerObjects {width: 95%; display: inline-block; margin-top: 20px; text-align: left;} + .BazSelectorContainerObjects li {display: inline-block; width: 120px; margin: 10px;word-wrap: break-word;} + .BazSelectorContainerObjects li a {font-size: 13px; font-weight: normal; padding: 3px 6px; margin: 0; border-radius: 0; display: inline-block;} + .BazSelectorContainerObjects li a img {width: 20px; height: 20px; vertical-align: middle;} + .BazSelectorContainerObjects li a p {display: inline;} + .BazzPreDescDisabled {display: none;} + .BazPrice {width: 100%; text-align: center;display: inline-block; font-weight: bold;} + .StableITBTNDisabled, .StableITBTNFDisabled {display: none;} + .StableITBTNActive, .StableITBTNFActive {display: inline-block;} + .StableITBTNFActive {font-size: 13px; padding: 5px 9px; margin-top: 5px;} + .ArrivaUniswap {position: fixed; width: 80%; height: 80%; overflow: hidden; z-index: 10;left: 10%;top: 10%;border: none;border-radius: 35px;} + .ArrivaUniswap img {width: 30%; position: absolute; left: 35%; top: 150px;} + .ArrivaUniswapQuelloVero iframe {position: fixed;width: 80%;height: 80%;overflow: hidden;left: 10%;top: 10%;z-index: 9;border: none;border-radius: 35px;} + .SeneVaUniswap {position: fixed; top: 10px; left: 50%; border-radius: 50%; width: 40px; height: 40px; line-height: 2.5; font: 12px; font-weight: bold; text-decoration: none;} .cover {max-height: 740px; width: 100%;} .UniBox {max-width: 300px;width: 100%; margin: 50px 10px 50px 10px;} .cover > img {width: 100%;} @@ -154,20 +311,39 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .featureActions a {padding: 4px 7px; font-size: 13px;} .unifiWelcome header {width: 350px;} .unifiWelcome header h2 {font-size: 18px;} + .StableCoinTitle, .grimoireWelcome {width: 100%; margin-top: 100px; text-align: center;position: initial;z-index: 1;} .coverMenu {margin: 50px auto 50px auto; width: 240px; border: 3px solid #bab9b9; border-radius: 8px; text-align: left; padding: 8px 5px;} .coverMenu li {width: 200; display: inline-block; position: relative; margin-left: 25px;} .coverMenu li a {width: 100%; display: inline-block; padding: 5px 5px; text-decoration: none;} .coverMenu li a img {width: 35px; height: 35px; margin: 0 7px; vertical-align: middle;} - .coverMenu li a span {font-size: 16px; font-weight: bolder; text-shadow:2px 2px 2px #5d5e60; color: #bab9b9; vertical-align: middle;} + .coverMenu li a span {font-size: 16px; font-weight: bolder; vertical-align: middle;} .coverMenu li .menuArrow {display: none;} .coverMenu li:hover .menuArrow {width: 20px; height: 20px; position: absolute; left: -15px; top: 15px; display: block;} .coverMenu .menuArrow img {width: 20px; height: 20px;} + .unifiDapp .MenuOpen {text-align: left; position: absolute; left: 90px; top: 50px; z-index: 99999999999999;} + .unifiDapp .MenuOpen .coverMenu {margin: 0;z-index: 99999999999999;outline: -webkit-focus-ring-color auto 0px;} .unifiWelcome .MenuOpen {display: inline-block !important;} .MenuOpen {width: 100%; display: inline-block; text-align: center;} - .StableCoinTitle .StableCoinTitleIntern, .grimoireWelcome .grimoireWelcomeIntern {width: 590px; padding: 20px; border-radius: 8px; display: inline-block;} + .StableCoinTitle .StableCoinTitleIntern, .grimoireWelcome .grimoireWelcomeIntern, .grimoireBox {width: 590px; padding: 20px; border-radius: 8px; display: inline-block;} .StableCoinTitleIntern article, .grimoireWelcomeIntern article {width: 480px; display: inline-block; vertical-align: middle;} - .StableCoinTitle img, .grimoireWelcome img {width: 80px; height: 80px; margin-right: 10px; vertical-align: middle;} + .StableCoinTitle img, .grimoireWelcome img {width: 80px; height: 80px; margin-right: 10px; vertical-align: middle; z-index: 1;} + .grimoireWelcome .GrimImg2 {width: 70px; height: 70px; position: absolute;bottom: -10px;left: -15px; z-index: 2;} footer .welcomeLinks, footer p {width: 500px; padding: 20px;} + .grimoireIndex {width: 350px;} + .DuGustis {position: relative;} + .BazSelectorContainer {width: 70%; left: 15%;} + .BazSelectorContainerMenuintern {width: 100%;} + .unifiDapp .MenuAll .connectOpener {float: right; margin-right: 20px; text-decoration: none;} + .unifiDapp .MenuAll .connectOpener img {width: 25px; height: 25px; vertical-align: middle;} + .unifiDapp .MenuAll .menuOpener, .unifiDapp .MenuAll .connectOpener span {font-size: 18px; font-weight: bold;} + .unifiDapp .MenuAll .connectOpener span {font-size: 18px; vertical-align: middle;} + .BoomerModeToggler {width: 35px; height: 35px; display: inline-block; text-align: center; border-radius: 10px; position: fixed; top: 10px; right: 230px; text-decoration: none;line-height: 2; font-size: 16px;} + .CallToGrim {display: inline-block;} + .unifiDapp .MenuAll .maghetto {width: 40px; height: 40px; float: left;margin: 5px 10px 0 20px;} + .grimoireIndex h2 {font-size: 30px; margin-bottom: 20px; margin-top: 0;} + .grimoireIndex a {width: 100%; padding: 20px 0; display: inline-block; font-size: 18px; vertical-align: middle;} + .grimoireIndex a img {width: 30px;height: 30px; margin-right: 6px; vertical-align: middle;} + } @media only screen and (min-width: 890px) { @@ -181,9 +357,12 @@ footer p a, footer h5 a {color: #c7ac97; font-weight: bold;} .featureActions a {padding: 4px 7px; font-size: 18px; border: 4px solid #5d5e60;} .unifiWelcome header {width: 500px;} .unifiWelcome header h2 {font-size: 20px;} - .StableCoinTitle .StableCoinTitleIntern, .grimoireWelcome .grimoireWelcomeIntern {width: 740px;} + .StableCoinTitle .StableCoinTitleIntern, .grimoireWelcome .grimoireWelcomeIntern, .grimoireBox {width: 740px;} .StableCoinTitleIntern article, .grimoireWelcomeIntern article {width: 590px;} .StableCoinTitle img, .grimoireWelcome img {width: 100px; height: 100px;} footer .welcomeLinks, footer p {width: 500px;} + .grimoireIndex {width: 450px;} + .BazSelectorContainer {width: 50%; left: 25%;} + .BazSelectorContainerMenuintern {width: 100%;} } \ No newline at end of file diff --git a/assets/img/eth-logo.png b/assets/img/eth-logo.png new file mode 100644 index 0000000..b2a42b8 Binary files /dev/null and b/assets/img/eth-logo.png differ diff --git a/assets/plugins/react/react.module.manager.js b/assets/plugins/react/react.module.manager.js index 2348f8c..e48feea 100644 --- a/assets/plugins/react/react.module.manager.js +++ b/assets/plugins/react/react.module.manager.js @@ -105,11 +105,11 @@ var ReactModuleManager = function() { if (rendered.props === undefined || rendered.props === null) { rendered.props = {}; } - rendered.props.className = loader ? rendered.props.defaultClassName : rendered.props.className; + rendered.props.className = loader && rendered.props.defaultClassName ? rendered.props.defaultClassName : rendered.props.className; if (rendered.props.className === undefined || rendered.props.className === null) { rendered.props.className = ''; } - if (!rendered.props.className.containsAloneWord(lowerCaseViewName)) { + if (rendered.props.className && !rendered.props.className.containsAloneWord(lowerCaseViewName)) { if (rendered.props.className !== '') { lowerCaseViewName += ' ' } @@ -247,7 +247,7 @@ var ReactModuleManager = function() { var element; var involveLoadedModules = true - if (typeof viewName !== 'string' || window[viewName] === undefined || window[viewName] instanceof HTMLCollection) { + if (typeof viewName !== 'string' || window[viewName] === undefined || window[viewName] instanceof HTMLCollection || window[viewName] instanceof HTMLElement) { element = React.createElement2.apply(React, callerArguments) involveLoadedModules = typeof viewName !== 'string' if (elementName !== undefined) { diff --git a/assets/scripts/script.js b/assets/scripts/script.js index fa05237..1b1a126 100644 --- a/assets/scripts/script.js +++ b/assets/scripts/script.js @@ -29,16 +29,33 @@ window.loadDFO = async function loadDFO(address, allAddresses) { var votingToken = window.voidEthereumAddress; try { - votingToken = (await window.blockchainCall(dfo.methods.getDelegates))[0]; - } catch (e) {} + var delegates = await window.web3.eth.call({ + to: element.dFO.options.address, + data: element.dFO.methods.getDelegates().encodeABI() + }); + try { + delegates = window.web3.eth.abi.decodeParameter("address[]", delegates); + } catch (e) { + delegates = window.web3.eth.abi.decodeParameters(["address", "address", "address", "address", "address", "address"], delegates); + } + votingToken = delegates[0]; + } catch (e) { + votingToken = undefined; + } - if (votingToken === window.voidEthereumAddress) { + if (!votingToken || votingToken === window.voidEthereumAddress) { try { votingToken = await window.blockchainCall(dfo.methods.getToken); } catch (e) {} } - if (votingToken === window.voidEthereumAddress) { + try { + await window.blockchainCall(window.newContract(window.context.votingTokenAbi, votingToken).methods.name); + } catch (e) { + votingToken = undefined; + } + + if (!votingToken || votingToken === window.voidEthereumAddress) { var logs = await window.getLogs({ address, topics: [ @@ -92,14 +109,6 @@ window.onEthereumUpdate = function onEthereumUpdate(millis) { window.ethereum && window.ethereum.on && window.ethereum.on('networkChanged', () => window.onEthereumUpdate(window.web3.currentProvider)); window.ethereum && window.ethereum.on && window.ethereum.on('accountsChanged', () => window.onEthereumUpdate(window.web3.currentProvider)); window.DFOHub(window.web3); - window.stableCoin = window.newContract(window.context.StableCoinAbi, window.getNetworkElement("stableCoinAddress")); - window.doubleProxy = window.newContract(window.context.DoubleProxyAbi, await window.blockchainCall(window.stableCoin.methods.doubleProxy)) - window.dfo = window.web3.eth.dfoHub.load(await window.blockchainCall(window.doubleProxy.methods.proxy)); - window.uniswapV2Router = window.newContract(window.context.UniswapV2RouterAbi, window.context.uniswapV2RouterAddress); - window.wethToken = window.newContract(window.context.votingTokenAbi, window.wethAddress = window.web3.utils.toChecksumAddress(await window.blockchainCall(window.uniswapV2Router.methods.WETH))); - window.uniswapV2Factory = window.newContract(window.context.UniswapV2FactoryAbi, window.context.uniswapV2FactoryAddress); - window.stableCoin = await window.loadTokenInfos(stableCoin.options.address, window.wethToken.options.address, window.context.StableCoinAbi); - window.votingToken = await window.loadTokenInfos((await (window.dfo = await window.dfo).votingToken).options.address, window.wethToken.options.address); update = true; } delete window.walletAddress; @@ -117,6 +126,20 @@ window.onEthereumUpdate = function onEthereumUpdate(millis) { }); }; +window.loadEthereumStuff = async function loadEthereumStuff(oldStableCoin) { + window.uniswapV2Router = window.newContract(window.context.UniswapV2RouterAbi, window.context.uniswapV2RouterAddress); + window.wethToken = window.newContract(window.context.votingTokenAbi, window.wethAddress = window.web3.utils.toChecksumAddress(await window.blockchainCall(window.uniswapV2Router.methods.WETH))); + window.uniswapV2Factory = window.newContract(window.context.UniswapV2FactoryAbi, window.context.uniswapV2FactoryAddress); + try { + window.stableCoin = window.newContract(window.context.StableCoinAbi, window.getNetworkElement(oldStableCoin ? "oldStableCoinAddress" : "stableCoinAddress")); + window.doubleProxy = window.newContract(window.context.DoubleProxyAbi, await window.blockchainCall(window.stableCoin.methods.doubleProxy)) + window.dfo = window.web3.eth.dfoHub.load(await window.blockchainCall(window.doubleProxy.methods.proxy)); + window.stableCoin = await window.loadTokenInfos(window.stableCoin.options.address, window.context.StableCoinAbi); + window.votingToken = await window.loadTokenInfos((await (window.dfo = await window.dfo).votingToken).options.address); + } catch(e) { + } +}; + window.getNetworkElement = function getNetworkElement(element) { var network = window.context.ethereumNetwork[window.networkId]; if (network === undefined || network === null) { @@ -212,6 +235,12 @@ window.getAddress = async function getAddress() { return (window.walletAddress = (await window.web3.eth.getAccounts())[0]); }; +window.consumeAddressBarParam = function consumeAddressBarParam(paramName) { + var param = window.addressBarParams[paramName]; + delete window.addressBarParams[paramName]; + return param; +}; + window.getSendingOptions = function getSendingOptions(transaction) { return new Promise(async function(ok, ko) { if (transaction) { @@ -1200,22 +1229,21 @@ window.eliminateFloatingFinalZeroes = function eliminateFloatingFinalZeroes(valu return split[1].length === 0 ? split[0] : split.join(decSeparator); }; -window.loadTokenInfos = async function loadTokenInfos(addresses, wethAddress, abi) { - wethAddress = wethAddress || await window.blockchainCall(window.newContract(window.context.uniSwapV2RouterAbi, window.context.uniSwapV2RouterAddress).methods.WETH); - wethAddress = window.web3.utils.toChecksumAddress(wethAddress); +window.loadTokenInfos = async function loadTokenInfos(addresses, abi, noLogo) { var single = (typeof addresses).toLowerCase() === 'string'; addresses = single ? [addresses] : addresses; var tokens = []; + window.tokenInfosCache = window.tokenInfosCache || {}; for (var address of addresses) { address = window.web3.utils.toChecksumAddress(address); var token = window.newContract(abi || window.context.votingTokenAbi, address); - tokens.push({ + tokens.push(window.tokenInfosCache[address] = window.tokenInfosCache[address] || { address, token, - name: address === wethAddress ? 'Ethereum' : await window.blockchainCall(token.methods.name), - symbol: address === wethAddress ? 'ETH' : await window.blockchainCall(token.methods.symbol), - decimals: address === wethAddress ? '18' : await window.blockchainCall(token.methods.decimals), - logo: await window.loadLogo(address === wethAddress ? window.voidEthereumAddress : address) + name: address === window.wethAddress ? 'Ethereum' : await window.blockchainCall(token.methods.name), + symbol: address === window.wethAddress ? 'ETH' : await window.blockchainCall(token.methods.symbol), + decimals: address === window.wethAddress ? '18' : await window.blockchainCall(token.methods.decimals), + logo: noLogo ? undefined : await window.loadLogo(address === window.wethAddress ? window.voidEthereumAddress : address) }); } return single ? tokens[0] : tokens; @@ -1272,4 +1300,50 @@ window.getEthereumPrice = async function getEthereumPrice() { price, requestExpires: new Date().getTime() + window.context.coingeckoEthereumPriceRequestInterval }).price; +}; + +window.loadUniswapPairs = async function loadUniswapPairs(token, indexes) { + window.pairCreatedTopic = window.pairCreatedTopic || window.web3.utils.sha3('PairCreated(address,address,address,uint256)'); + var address = window.web3.utils.toChecksumAddress(token.address); + if (address === window.voidEthereumAddress) { + address = window.wethAddress; + } + var myToken = window.web3.eth.abi.encodeParameter('address', address); + var logs = await window.getLogs({ + address: window.context.uniSwapV2FactoryAddress, + fromBlock: '0', + topics: [ + window.pairCreatedTopic, [myToken] + ] + }); + logs.push(...(await window.getLogs({ + address: window.context.uniSwapV2FactoryAddress, + fromBlock: '0', + topics: [ + window.pairCreatedTopic, [], + [myToken] + ] + }))); + var uniswapPairs = []; + var alreadyAdded = {}; + for (var log of logs) { + for (var topic of log.topics) { + if (topic === window.pairCreatedTopic || topic.toLowerCase() === myToken.toLowerCase()) { + continue; + } + var pairTokenAddress = window.web3.utils.toChecksumAddress(window.web3.eth.abi.decodeParameters(['address', 'uint256'], log.data)[0]); + if (alreadyAdded[pairTokenAddress]) { + continue; + } + alreadyAdded[pairTokenAddress] = true; + var pairToken = await window.loadTokenInfos(pairTokenAddress, window.context.UniswapV2PairAbi, true); + var token0 = window.web3.utils.toChecksumAddress(await window.blockchainCall(pairToken.token.methods.token0)); + var token1 = window.web3.utils.toChecksumAddress(await window.blockchainCall(pairToken.token.methods.token1)); + pairToken.token0 = token0 === address ? token : await window.loadTokenInfos(token0, undefined, true); + pairToken.token1 = token1 === address ? token : await window.loadTokenInfos(token1, undefined, true); + pairToken.key = `${token0}_${token1}-${token1}_${token0}`; + uniswapPairs.push(indexes[pairToken.key] = pairToken); + } + } + return uniswapPairs; }; \ No newline at end of file diff --git a/contracts/stableCoin/microservices/IERC20.sol b/contracts/stableCoin/microservices/IERC20.sol index 28bb3b9..ac0d35e 100644 --- a/contracts/stableCoin/microservices/IERC20.sol +++ b/contracts/stableCoin/microservices/IERC20.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; interface IERC20 { function mint(uint256 amount) external; diff --git a/contracts/stableCoin/microservices/IMVDFunctionalitiesManager.sol b/contracts/stableCoin/microservices/IMVDFunctionalitiesManager.sol index 64d9e03..72d2e2d 100644 --- a/contracts/stableCoin/microservices/IMVDFunctionalitiesManager.sol +++ b/contracts/stableCoin/microservices/IMVDFunctionalitiesManager.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; interface IMVDFunctionalitiesManager { function isAuthorizedFunctionality(address functionality) external view returns (bool); diff --git a/contracts/stableCoin/microservices/IMVDProxy.sol b/contracts/stableCoin/microservices/IMVDProxy.sol index fbfd67c..a3021d5 100644 --- a/contracts/stableCoin/microservices/IMVDProxy.sol +++ b/contracts/stableCoin/microservices/IMVDProxy.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; interface IMVDProxy { function getToken() external view returns (address); diff --git a/contracts/stableCoin/microservices/IStateHolder.sol b/contracts/stableCoin/microservices/IStateHolder.sol index a53be3d..2997b68 100644 --- a/contracts/stableCoin/microservices/IStateHolder.sol +++ b/contracts/stableCoin/microservices/IStateHolder.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; interface IStateHolder { function clear(string calldata varName) diff --git a/contracts/stableCoin/microservices/MintNewVotingTokensForStableCoinFunctionality.sol b/contracts/stableCoin/microservices/MintNewVotingTokensForStableCoinFunctionality.sol index 3574a15..bca8987 100644 --- a/contracts/stableCoin/microservices/MintNewVotingTokensForStableCoinFunctionality.sol +++ b/contracts/stableCoin/microservices/MintNewVotingTokensForStableCoinFunctionality.sol @@ -1,6 +1,22 @@ +/* Discussion: + * https://github.com/b-u-i-d-l/unifi + */ +/* Description: + * When a stablecoin loses value, the Uniswap Tier pools rebalance to an uneven disparity (≠ 50/50). If the stablecoin totally fails, the other stablecoins effectively pump in correlation. + * + * DFO Debit resolves this issue on-chain by rebalancing uSD, creating debt which the UniFi DFO then pays off by minting UniFi. Let’s look at how this plays out, step by step: + * + * 1 - A stablecoin collateralized by uSD loses value or fails altogether. + * + * 2 - $UniFi holders vote to remove the tiers containing the failed stablecoin from the whitelist.The uSD supply becomes grater than the supply of the collateralized pooled stablecoins. + * + * 3 - To restore 1:1 equilibrium, anyone holding uSD can burn it to receive new UniFi, minted at a 50% discount of the uSD/UniFi Uniswap pool mid-price ratio. + * + * The goal of $UniFi holders, which aligns with their self-interest, is to ensure uSD’s security. Thus there is an economic disincentive to whitelist insecure stablecoins. + */ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity 0.7.0; import "./IERC20.sol"; import "./IMVDFunctionalitiesManager.sol"; @@ -14,7 +30,7 @@ import "./IStateHolder.sol"; contract MintNewVotingTokensForStableCoinFunctionality { function onStart(address, address) public { IStateHolder stateHolder = IStateHolder(IMVDProxy(msg.sender).getStateHolderAddress()); - address stablecoinauthorized = 0x9f4c43A51C9a67F432E5C8BcBFa55312110BCD3A; + address stablecoinauthorized = 0x44086035439E676c02D411880FcCb9837CE37c57; stateHolder.setBool( _toStateHolderKey("stablecoin.authorized", _toString(stablecoinauthorized)), true @@ -23,7 +39,7 @@ contract MintNewVotingTokensForStableCoinFunctionality { function onStop(address) public { IStateHolder stateHolder = IStateHolder(IMVDProxy(msg.sender).getStateHolderAddress()); - address stablecoinauthorized = 0x9f4c43A51C9a67F432E5C8BcBFa55312110BCD3A; + address stablecoinauthorized = 0x44086035439E676c02D411880FcCb9837CE37c57; stateHolder.clear( _toStateHolderKey("stablecoin.authorized", _toString(stablecoinauthorized)) ); @@ -37,7 +53,6 @@ contract MintNewVotingTokensForStableCoinFunctionality { ) public { IMVDProxy proxy = IMVDProxy(msg.sender); - // NOTE: Use DFO Protocol to check for authorization require( IStateHolder(proxy.getStateHolderAddress()).getBool( _toStateHolderKey("stablecoin.authorized", _toString(sender)) diff --git a/contracts/stableCoin/standalone/Address.sol b/contracts/stableCoin/standalone/Address.sol index 4af9fb8..6b28275 100644 --- a/contracts/stableCoin/standalone/Address.sol +++ b/contracts/stableCoin/standalone/Address.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @dev Collection of functions related to the address type diff --git a/contracts/stableCoin/standalone/Context.sol b/contracts/stableCoin/standalone/Context.sol index a193e82..97c73c4 100644 --- a/contracts/stableCoin/standalone/Context.sol +++ b/contracts/stableCoin/standalone/Context.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @dev Provides information about the current execution context, including the diff --git a/contracts/stableCoin/standalone/ERC20.sol b/contracts/stableCoin/standalone/ERC20.sol index cddefcf..126be42 100644 --- a/contracts/stableCoin/standalone/ERC20.sol +++ b/contracts/stableCoin/standalone/ERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; import "./Context.sol"; import "./IERC20.sol"; diff --git a/contracts/stableCoin/standalone/IDoubleProxy.sol b/contracts/stableCoin/standalone/IDoubleProxy.sol index 0ddd2d2..5b6c101 100644 --- a/contracts/stableCoin/standalone/IDoubleProxy.sol +++ b/contracts/stableCoin/standalone/IDoubleProxy.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; // DOCUMENT interface IDoubleProxy { diff --git a/contracts/stableCoin/standalone/IERC20.sol b/contracts/stableCoin/standalone/IERC20.sol index 841d27a..82708eb 100644 --- a/contracts/stableCoin/standalone/IERC20.sol +++ b/contracts/stableCoin/standalone/IERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. diff --git a/contracts/stableCoin/standalone/IMVDFunctionalitiesManager.sol b/contracts/stableCoin/standalone/IMVDFunctionalitiesManager.sol index c68f7c5..a99e8f2 100644 --- a/contracts/stableCoin/standalone/IMVDFunctionalitiesManager.sol +++ b/contracts/stableCoin/standalone/IMVDFunctionalitiesManager.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; // DOCUMENT interface IMVDFunctionalitiesManager { diff --git a/contracts/stableCoin/standalone/IMVDProxy.sol b/contracts/stableCoin/standalone/IMVDProxy.sol index 83657ea..b4c6d23 100644 --- a/contracts/stableCoin/standalone/IMVDProxy.sol +++ b/contracts/stableCoin/standalone/IMVDProxy.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; // DOCUMENT interface IMVDProxy { diff --git a/contracts/stableCoin/standalone/IStableCoin.sol b/contracts/stableCoin/standalone/IStableCoin.sol index ba8745f..b5b5642 100644 --- a/contracts/stableCoin/standalone/IStableCoin.sol +++ b/contracts/stableCoin/standalone/IStableCoin.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @title Interface for the $uSD aka unified Stable Dollar. diff --git a/contracts/stableCoin/standalone/IStateHolder.sol b/contracts/stableCoin/standalone/IStateHolder.sol index c3b0e3f..9a23fb8 100644 --- a/contracts/stableCoin/standalone/IStateHolder.sol +++ b/contracts/stableCoin/standalone/IStateHolder.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; // DOCUMENT interface IStateHolder { diff --git a/contracts/stableCoin/standalone/IUniswapV2Pair.sol b/contracts/stableCoin/standalone/IUniswapV2Pair.sol index 2a1c7b3..7658298 100644 --- a/contracts/stableCoin/standalone/IUniswapV2Pair.sol +++ b/contracts/stableCoin/standalone/IUniswapV2Pair.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; // DOCUMENT /** diff --git a/contracts/stableCoin/standalone/IUniswapV2Router.sol b/contracts/stableCoin/standalone/IUniswapV2Router.sol index ae81a16..eb3849b 100644 --- a/contracts/stableCoin/standalone/IUniswapV2Router.sol +++ b/contracts/stableCoin/standalone/IUniswapV2Router.sol @@ -1,4 +1,4 @@ -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @title Uniswap V2 Router diff --git a/contracts/stableCoin/standalone/SafeMath.sol b/contracts/stableCoin/standalone/SafeMath.sol index 541864b..b2e90e8 100644 --- a/contracts/stableCoin/standalone/SafeMath.sol +++ b/contracts/stableCoin/standalone/SafeMath.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow diff --git a/contracts/stableCoin/standalone/StableCoin.sol b/contracts/stableCoin/standalone/StableCoin.sol index 6d5a952..5cc7394 100644 --- a/contracts/stableCoin/standalone/StableCoin.sol +++ b/contracts/stableCoin/standalone/StableCoin.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.7.0; +pragma solidity ^0.6.0; import "./ERC20.sol"; import "./IStableCoin.sol"; diff --git a/data/context.json b/data/context.json index f5021bc..12527d5 100644 --- a/data/context.json +++ b/data/context.json @@ -3,6 +3,14 @@ "1": "", "3": "Ropsten" }, + "domainData" : { + "name" : "unifi.com", + "sections" : { + "bazar" : "swapBazar", + "usd" : "stableCoin", + "grimoire" : "grimoire" + } + }, "switchWebsite" : "https://switch.dfohub.com", "gitHubURL" : "https://github.com/b-u-i-d-l/brand-contest", "etherscanURL": "https://etherscan.io/", @@ -10,17 +18,33 @@ "coingeckoEthereumPriceURL": "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids=ethereum", "coingeckoEthereumPriceRequestInterval": 600000, "trustwalletImgURLTemplate": "https://raw.githubusercontent.com/trustwallet/assets/master/blockchains/ethereum/assets/{0}/logo.png", - "stableCoinAddressRopsten" : "0x9f4c43A51C9a67F432E5C8BcBFa55312110BCD3A", - "stableCoinAddress" : "0x04C2d7C0712089a61C52A315FCe8F28a55F34DFa", - "infuraNode" : "https://ropsten.infura.io/v3/5e302428cc5e41a188dc717dc6f34a5b", + "uniswapDappLinkTemplate" : "https://app.uniswap.org/#/{0}?inputCurrency={1}&outputCurrency={2}&theme={3}", + "uniswapDappLinkTemplatePool" : "https://app.uniswap.org/#/{0}/{1}-{2}?theme={3}", + "uniswapInfoLinkTemplate" : "https://uniswap.info/token/{0}", + "stableCoinAddressRopsten" : "0xD73E0a13AcA6E7FCF1141Ff00Ab7625cf5A93287", + "stableCoinAddress" : "0x44086035439E676c02D411880FcCb9837CE37c57", + "oldStableCoinAddressRopsten" : "0xba6d34a9c638270a5393772b0b45b528e12eb9a4", + "oldStableCoinAddress" : "0x84841e552A021224de716b7Be89747bb2D62D642", + "infuraNode" : "https://mainnet.infura.io/v3/5e302428cc5e41a188dc717dc6f34a5b", + "uniwsapOfficialTokensList" : "https://unpkg.com/@uniswap/default-token-list@latest", + "indexesURL" : "https://raw.githubusercontent.com/b-u-i-d-l/bazar-tokens-list/master/dist/indexes.json", + "programmableEquitiesURL" : "https://raw.githubusercontent.com/b-u-i-d-l/bazar-tokens-list/master/dist/programmableEquities.json", + "uniswapTokensURL" : "https://raw.githubusercontent.com/b-u-i-d-l/bazar-tokens-list/master/dist/uniswapTokens.json", "uniswapV2RouterAddress" : "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "uniSwapV2FactoryAddress" : "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", + "dfoAddress": "0xc3BE549499f1e504c793a6c89371Bd7A98229500", + "dfoAddressRopsten": "0x761E02FEC5A21C6d3F284bd536dB2D2d33d5540B", + "uSDPoolLimit" : 10000, "blockSearchSection" : 9000000, + "deploySearchStart": 9779603, + "deploySearchStartRopsten": 7465062, + "refreshDataPollingInterval" : 10000, "typeTimeout" : 600, "defaultCharsAmount" : 90, "transactionConfirmations": 0, "transactionConfirmationsTimeoutMillis": 7000, "slippageAmount" : 0.005, + "proxyAbi": [{"inputs":[{"internalType":"address","name":"location","type":"address"},{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"callFromManager","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAddress","type":"address"},{"internalType":"bytes","name":"initPayload","type":"bytes"}],"name":"changeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"position","type":"uint256"},{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"},{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"DelegateChanged","type":"event"},{"inputs":[{"internalType":"address","name":"proposalAddress","type":"address"}],"name":"disableProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"eventSignature","type":"string"},{"internalType":"bytes","name":"firstIndex","type":"bytes"},{"internalType":"bytes","name":"secondIndex","type":"bytes"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"emitEvent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"codeName","type":"string"},{"internalType":"address","name":"proposal","type":"address"},{"internalType":"string","name":"replaced","type":"string"},{"internalType":"address","name":"replacedSourceLocation","type":"address"},{"internalType":"uint256","name":"replacedSourceLocationId","type":"uint256"},{"internalType":"address","name":"location","type":"address"},{"internalType":"bool","name":"submitable","type":"bool"},{"internalType":"string","name":"methodSignature","type":"string"},{"internalType":"bool","name":"isInternal","type":"bool"},{"internalType":"bool","name":"needsSender","type":"bool"},{"internalType":"address","name":"proposalAddress","type":"address"}],"name":"emitFromManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"key","type":"string"},{"indexed":true,"internalType":"bytes32","name":"firstIndex","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"secondIndex","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Event","type":"event"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"bool","name":"is721","type":"bool"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"flushToWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"codeName","type":"string"},{"indexed":true,"internalType":"address","name":"proposal","type":"address"},{"indexed":false,"internalType":"string","name":"replaced","type":"string"},{"indexed":false,"internalType":"address","name":"replacedSourceLocation","type":"address"},{"indexed":false,"internalType":"uint256","name":"replacedSourceLocationId","type":"uint256"},{"indexed":true,"internalType":"address","name":"replacedLocation","type":"address"},{"indexed":false,"internalType":"bool","name":"replacedWasSubmitable","type":"bool"},{"indexed":false,"internalType":"string","name":"replacedMethodSignature","type":"string"},{"indexed":false,"internalType":"bool","name":"replacedWasInternal","type":"bool"},{"indexed":false,"internalType":"bool","name":"replacedNeededSender","type":"bool"},{"indexed":true,"internalType":"address","name":"replacedProposal","type":"address"}],"name":"FunctionalitySet","type":"event"},{"inputs":[{"internalType":"address","name":"votingTokenAddress","type":"address"},{"internalType":"address","name":"functionalityProposalManagerAddress","type":"address"},{"internalType":"address","name":"stateHolderAddress","type":"address"},{"internalType":"address","name":"functionalityModelsManagerAddress","type":"address"},{"internalType":"address","name":"functionalitiesManagerAddress","type":"address"},{"internalType":"address","name":"walletAddress","type":"address"},{"internalType":"address","name":"doubleProxyAddress","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"codeName","type":"string"},{"internalType":"bool","name":"emergency","type":"bool"},{"internalType":"address","name":"sourceLocation","type":"address"},{"internalType":"uint256","name":"sourceLocationId","type":"uint256"},{"internalType":"address","name":"location","type":"address"},{"internalType":"bool","name":"submitable","type":"bool"},{"internalType":"string","name":"methodSignature","type":"string"},{"internalType":"string","name":"returnParametersJSONArray","type":"string"},{"internalType":"bool","name":"isInternal","type":"bool"},{"internalType":"bool","name":"needsSender","type":"bool"},{"internalType":"string","name":"replaces","type":"string"}],"name":"newProposal","outputs":[{"internalType":"address","name":"proposalAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"proposal","type":"address"}],"name":"Proposal","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposal","type":"address"}],"name":"ProposalCheck","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"proposal","type":"address"},{"indexed":false,"internalType":"bool","name":"success","type":"bool"}],"name":"ProposalSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"}],"name":"ProxyChanged","type":"event"},{"inputs":[{"internalType":"uint256","name":"position","type":"uint256"},{"internalType":"address","name":"newAddress","type":"address"}],"name":"setDelegate","outputs":[{"internalType":"address","name":"oldAddress","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"proposalAddress","type":"address"}],"name":"startProposal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"codeName","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"submit","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"token","type":"address"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"internalType":"bool","name":"safe","type":"bool"},{"internalType":"address","name":"token","type":"address"}],"name":"transfer721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDelegates","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDoubleProxyAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMVDFunctionalitiesManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMVDFunctionalityModelsManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMVDFunctionalityProposalManagerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMVDWalletAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStateHolderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"functionality","type":"address"}],"name":"isAuthorizedFunctionality","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"proposal","type":"address"}],"name":"isValidProposal","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"codeName","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"read","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"view","type":"function"}], "StableCoinAbi" : [{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"doubleProxy","type":"address"},{"internalType":"address[]","name":"allowedPairs","type":"address[]"},{"internalType":"uint256[]","name":"rebalanceRewardMultiplier","type":"uint256[]"},{"internalType":"uint256[]","name":"timeWindows","type":"uint256[]"},{"internalType":"uint256[]","name":"mintables","type":"uint256[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowedPairs","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableToMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"pairAmount","type":"uint256"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"burn","outputs":[{"internalType":"uint256","name":"removed0","type":"uint256"},{"internalType":"uint256","name":"removed1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"burnt","type":"uint256"}],"name":"calculateRebalanceByDebtReward","outputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"differences","outputs":[{"internalType":"uint256","name":"credit","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doubleProxy","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"fromTokenToStable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"doubleProxy","type":"address"},{"internalType":"address[]","name":"allowedPairs","type":"address[]"},{"internalType":"uint256[]","name":"rebalanceRewardMultiplier","type":"uint256[]"},{"internalType":"uint256[]","name":"timeWindows","type":"uint256[]"},{"internalType":"uint256[]","name":"mintables","type":"uint256[]"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"minted","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"pairIndex","type":"uint256"},{"internalType":"uint256","name":"pairAmount","type":"uint256"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"rebalanceByCredit","outputs":[{"internalType":"uint256","name":"redeemed","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rebalanceByDebt","outputs":[{"internalType":"uint256","name":"reward","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebalanceRewardMultiplier","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"newAllowedPairs","type":"address[]"}],"name":"setAllowedPairs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newDoubleProxy","type":"address"}],"name":"setDoubleProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tierData","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}], "UniswapV2RouterAbi" : [{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}], "UniswapV2FactoryAbi" : [{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0","type":"address"},{"indexed":true,"internalType":"address","name":"token1","type":"address"},{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"PairCreated","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allPairs","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allPairsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"createPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeTo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToSetter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"getPair","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"}], diff --git a/index.html b/index.html index 55bf773..9da57a2 100644 --- a/index.html +++ b/index.html @@ -1,8 +1,8 @@ - + - Unifi | Uniswap Finance + UniFi | DeFi on top of Uniswap @@ -39,10 +39,10 @@ -
- -

Welcome to the UniFi World

-
+
+ +

Welcome to the UniFi World

+
\ No newline at end of file diff --git a/spa/banner.jsx b/spa/banner.jsx index a11c252..d8295e2 100644 --- a/spa/banner.jsx +++ b/spa/banner.jsx @@ -6,7 +6,7 @@ var Banner = React.createClass({ Continue as a Mage 🧙‍♂️ Continue as an Etherean Hacker 👩‍💻 Continue, but not interested in this millennials things -

Use it at your own risk! This is an R&D project in it's early stage [Beta 0.5]. Before to use UniFi related functions be sure to read the documentation and Smart Contracts code. All of the Functions of UniFi work on top of Uniswap, Before use them be sure to read how Uniswap work: Ethhub Uniswap Guide | Uniswap Returns Guide | Advanced Uniswap Guide

+

Use it at your own risk! This is an R&D project in it's early stage [Beta 0.5]. Before to use UniFi related functions be sure to read the documentation and Smart Contracts code. All of the Functions of UniFi work on top of Uniswap, Before use them be sure to read how the Uniswap protocol works: Ethhub Uniswap Guide | Uniswap Returns Guide | Advanced Uniswap Guide

); } diff --git a/spa/dappMenu/view.jsx b/spa/dappMenu/view.jsx index d9ff23e..a126523 100644 --- a/spa/dappMenu/view.jsx +++ b/spa/dappMenu/view.jsx @@ -18,10 +18,22 @@ var DappMenu = React.createClass({ icon: "m4" }, { title: "Liquidity Crafting", - icon: "m2" + icon: "m2", + props : { + onClick: () => this.emit("section/change", "grimoire", { + href : "#grimCraft" + }), + href: "#grimCraft" + } }, { title: "Liquidity Offering", - icon: "m5" + icon: "m5", + props : { + onClick: () => this.emit("section/change", "grimoire", { + href : "#grimCraft" + }), + href: "#grimCraft" + } }, { title: "Swap Bazar", icon: "m1" @@ -30,7 +42,11 @@ var DappMenu = React.createClass({ icon: "m0" }, { title: "Github", - icon: "m3" + icon: "m3", + props : { + href: "https://github.com/b-u-i-d-l/unifi", + target: "_blank" + } }] }; }, @@ -60,22 +76,27 @@ var DappMenu = React.createClass({ state[type] = !(_this.state && _this.state[type]); _this[type] && delete _this[type].onblur; _this.setState(state, function() { - _this.state[type] && _this[type] && !_this[type].onblur && (_this[type].onblur = function(e) { + _this.state[type] && _this[type] && (_this[type].onblur = _this[type].onblur || function(e) { e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); e.relatedTarget && e.relatedTarget !== oldTarget && e.relatedTarget.click(); - //toggleWork(type); + e.relatedTarget !== oldTarget && toggleWork(type); }) && _this[type].focus(); }); }; toggleWork(e.currentTarget.dataset.type); }, + toggleBoomerMode(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.emit('visual/mode/toggle'); + }, render() { return (
+ ref && (ref.innerHTML = ('&#' + (window.localStorage.boomerMode === 'true' ? '128188' : '10024') + ';'))}> Menu {!window.walletAddress && Connect} - {window.walletAddress && {window.shortenWord(window.walletAddress, 12)}} + {window.walletAddress && {window.shortenWord(window.walletAddress, 12)}}
this.menu = ref} className="coverMenu" tabIndex="-1"> {this.state.menuItems.map(this.renderMenuItem)} diff --git a/spa/explainer/view.jsx b/spa/explainer/view.jsx index 9786c33..5eb2bf2 100644 --- a/spa/explainer/view.jsx +++ b/spa/explainer/view.jsx @@ -1,24 +1,18 @@ var Explainer = React.createClass({ - requiredScripts: [ - 'spa/loader.jsx' - ], - requiredModules: [ - 'spa/dappMenu' - ], renderExStableCoin() { - return this.renderInput("ExStableCoin", "assets/img/exp1.png", "a", "InfoButton", "a", "dappButton", "More", "Launch Dapp", "A Stable Coin to Pool Them All", "Uniswap State Dollar (uSD) is a new stablecoin minted by the magic rainbow of Uniswap stablecoin pools. Backed by the power of the Unicorn, uSD is the most secure stablecoin ever. The only way it could be destabilized is if the entire stablecoin industry crashed.", undefined, () => this.emit('section/change', 'stableCoin')); + return this.renderInput("ExStableCoin", "assets/img/exp1.png", "a", "InfoButton", "a", "dappButton", "More", "Launch Dapp", "A Stable Coin to Pool Them All", "Unified Stable Dollar (uSD) is a new stablecoin minted by the magic rainbow of Uniswap stablecoin pools. Backed by the power of the Unicorn, uSD is the most secure stablecoin ever. The only way it could be destabilized is if the entire stablecoin industry crashed.", () => this.emit('section/change', 'grimoire', {href: "#grimuSD"}), () => this.emit('section/change', 'stableCoin')); }, renderExCrafting() { - return this.renderInput("ExCrafting", "assets/img/exp0.png", "a", "InfoButton", "a", "soonButton", "More", "Coming Soon", "Crafting Programmable Liquidity", "Craft makes it possible to provide liquidity that is programmable with advanced rules. Using Unicorn magic, pools can balance tokens diversely with unprecedented security."); + return this.renderInput("ExCrafting", "assets/img/exp0.png", "a", "InfoButton", "a", "soonButton", "More", "Coming Soon", "Crafting Programmable Liquidity", "Craft makes it possible to provide liquidity that is programmable with advanced rules. Using Unicorn magic, pools can balance tokens diversely with unprecedented security.", () => this.emit('section/change', 'grimoire', {href: "#grimCraft"})); }, renderExIlo() { - return this.renderInput("ExIlo", "assets/img/exp4.png", "a", "InfoButton", "a", "soonButton", "More", "Coming Soon", "ILOs Offering Tokens for Liquidity", "The Initial Liquidity Offering (ILO) is a new way for startups to provide that liquidity. By using Craft, ILOs offer total security against Sniper Bots, a new villain in the Unicorn Story."); + return this.renderInput("ExIlo", "assets/img/exp4.png", "a", "InfoButton", "a", "soonButton", "More", "Coming Soon", "ILOs Offering Tokens for Liquidity", "The Initial Liquidity Offering (ILO) is a new way for startups to provide that liquidity. By using Craft, ILOs offer total security against Sniper Bots, a new villain in the Unicorn Story.", () => this.emit('section/change', 'grimoire', {href: "#grimCraft"})); }, renderExDex() { - return this.renderInput("ExDex", "assets/img/exp3.png", "a", "InfoButton", "a", "dappButton", "More", "Launch Dapp", "Swap More Than Just Tokens", "Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities, Token Indexes and NFTs (including ERC 1155 NFTs, thanks to ethArt V2) can now be swapped, on the new Bazaar DEX.", undefined, () => this.emit('section/change', 'swapBazar')); + return this.renderInput("ExDex", "assets/img/exp3.png", "a", "InfoButton", "a", "dappButton", "More", "Launch Dapp", "Swap More Than Just Tokens", "Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities, Token Indexes and NFTs (including ERC 1155 NFTs, thanks to ethArt V2) can now be swapped, on the new Bazaar DEX.", () => this.emit('section/change', 'grimoire', {href: "#grimBaz"}), () => this.emit('section/change', 'swapBazar')); }, renderExGrimoire() { - return this.renderInput("ExGrimoire", "assets/img/exp2.png", "a", "readButton", "a", "gitButton", "Read", "Github", "Unicorn Magic For Dummies", "The Official guide for using Uniswap Unicorn magic. Grimoire, the best selling book of 2020, is prescribed by all the top wizard Universities, and won this years' Booker Prize."); + return this.renderInput("ExGrimoire", "assets/img/exp2.png", "a", "readButton", "a", "gitButton", "Read", "Github", "Unicorn Magic For Dummies", "The Official guide for using Unicorn magic with the DeFi on the top of Uniswap. Grimoire, the best selling book of 2020, is prescribed by all the top wizard Universities, and won this years' Booker Prize.", () => this.emit('section/change', 'Grimoire'), "https://github.com/b-u-i-d-l/unifi"); }, renderInput(expFeature, featureIllustration, featureActionA, featureActionAStyle, featureActionB, featureActionBStyle, featureBtnA, featureBtnB, featureTitle, featureDesc, actionA, actionB) { return ( @@ -31,14 +25,18 @@ var Explainer = React.createClass({

{featureTitle}

{featureDesc}

); }, + openStableCoin(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.emit('section/change', 'stableCoin', {oldStableCoin : true}) + }, render() { return (
@@ -46,7 +44,7 @@ var Explainer = React.createClass({
-

A Decentralized finance on top of Uniswap, doing fantastic things securelly

+

Decentralized Finance on top of Uniswap, doing fantastic things securely

{this.renderExStableCoin()} @@ -70,8 +68,9 @@ var Explainer = React.createClass({ Uniswap DeFi Pulse Etherscan + Redeem from the old StableCoin
-

Use it at your own risk! This is an R&D project in it's early stage [Beta]. Before to use UniFi related functions be sure to read the documentation and Smart Contracts code. All of the Functions of UniFi work on top of Uniswap, Before use them be sure to read how Uniswap work: Ethhub Uniswap Guide | Uniswap Returns Guide | Advanced Uniswap Guide

+

Use at your own risk! This is an R&D project in its early stage [Beta]. Before using UniFi related functions, be sure to read the documentation and Smart Contracts code. All of the functions of UniFi work on top of Uniswap, so be sure about how Uniswap DeFi protocol works too: Ethhub Uniswap Guide | Uniswap Returns Guide | Advanced Uniswap Guide

diff --git a/spa/grimoire/grimBazar.jsx b/spa/grimoire/grimBazar.jsx new file mode 100644 index 0000000..5d1a881 --- /dev/null +++ b/spa/grimoire/grimBazar.jsx @@ -0,0 +1,48 @@ +var GrimBazar = React.createClass({ + requiredScripts: [ + 'spa/loader.jsx' + ], + + render() { + return ( +
+
+
+ +
+

The Grimoire - The Bazar

+
Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities, Token Indexes and NFTs (including ERC 1155 NFTs, thanks to ethArt V2) can now be swapped, on the new Bazaar DEX.
+
+
+
+
+
+ +
+

Basics

+

The UniFi Bazar unleashes the true potential of Decentralized Finance on top of Uniswap, by enabling Ethereans to trade Index Funds, Programmable Equities and NFTs more easily than ever before.

+
+
+

Listing

+

Index Funds

+

Previously, any ERC20 Uniswap V2 pool token could be traded on Uniswap. But Index Funds—backed by multiple ERC20 tokens—could not. Until now.

+
On the Bazar, Ethereans can freely swap and track crypto Index Funds.
+

Programmable Equities

+

Programmable equities are a new asset class in crypto. They are the ERC20 voting tokens of Decentralized Flexible Organizations (DFOs). Holders have 100% ownership of the protocol; there is no opportunity for external manipulation.

+
On the Bazar, all programmable equities can be listed and traded on Uniswap.
+

Non-Fungible Tokens (NFTs)

+

ERC1155 NFTs are tokens with metadata, but at the same time have a supply. The reason they haven’t been tradable in AMMs before is due to their ‘transfer’ function. They use the ‘SafeTransferFrom’ method, instead of the ERC20 methods, ‘Transfer’ and ‘TransferFrom.’ Also, they don’t have decimals; they’re transferred using ID and Amount.

+

ethArt V2 will be released in November, and the Bazar will be able to synthesize ERC1155 tokens with an ERC20 (à la WETH with ETH) in the background, fundamentally reshaping the NFT market by allowing Ethereans to trade ERC1155 tokens for the first time.

+

Swappable ERC 1155 release

+

The release of ethArt V2 and swappable NFTs is scheduled for late November using ethArt V2

+
+
+
+
+ ); + } +}); \ No newline at end of file diff --git a/spa/grimoire/grimCrafting.jsx b/spa/grimoire/grimCrafting.jsx new file mode 100644 index 0000000..30de93e --- /dev/null +++ b/spa/grimoire/grimCrafting.jsx @@ -0,0 +1,85 @@ +var GrimCrafting = React.createClass({ + requiredScripts: [ + 'spa/loader.jsx' + ], + + render() { + return ( +
+
+
+ +
+

The Grimoire - Crafting and Initial Liquidity Offering

+
Craft makes it possible to provide liquidity that is programmable with advanced rules. Using Unicorn magic, pools can balance tokens diversely with unprecedented security.
+
+
+
+
+
+ +
+

Basics

+

Programmable liquidity is an exciting new feature in AMMs (Automated Market Makers). However, if not applied correctly, it can actually be a security hole for bugs, due to math complexities (as we saw with Balancer recently).

+

UniFi Crafting resolves this by offering programmable liquidity, but with Uniswap as base DeFi layer, taking advantage of its secure and decentralized core. This also helps liquidity providers customize their investments, and empowers new applications on top of Uniswap.

+

How Does It Work?

+

Uniswap allows for liquidity pools composed of 50:50 asset ratios. This is usually the most secure setup for an AMM, but disincentivizes liquidity provision by incurring impermanent losses. Crafting resolves this, and opens up novel financial use cases for Uniswap pools. It is a fancy new way to build liquidity together, without needing to trust and know each other.

+

Anyone can create a Craft order, customize the liquidity setup and deploy it by contributing some of the liquidity. Others can then contribute the rest required to pool the order on Uniswap. Later, after the predetermined block, any of the participants can trigger removal of the liquidity. It is then distributed to all order participants based on the predetermined rules.

+
+
+

Programmable Liquidity Rules

+
With Crafting, Uniswap liquidity providers can program a liquidity order by customizing the following:
+
    +
  1. - Tier: The Uniswap tier to which the liquidity will added.
  2. +
  3. - Waiting Length: The max time (in blocks) the order can remain available while the required liquidity is waiting to be filled.
  4. +
  5. - Min Block Length: The time (in blocks) for which the liquidity will be locked. If 0, any participant can trigger the removal of liquidity anytime.
  6. +
  7. - Liquidity Ratio: The ratio of liquidity, e.g. 10% DAI - 90% ETH or 0% DAI - 100 ETH. Once deployed by the creator, others can add the required liquidity. If the creator sets the ratio at 10% DAI - 90% ETH, the others can add the rest at 90% DAI - 10% ETH.
  8. +
  9. - Liquidity Exit/Discount: An advanced feature for orders that allows for the creation of a different ratio or even a discount for the exit.
  10. +
+

Let’s play out that aforementioned example.

+

Person A creates an order for USDC - DAI, with a min block length of 543055 Blocks and a ratio of 10% DAI - 90% USDC. He adds 100 DAI and 900 USDC, and also decides to set the exit liquidity at 30% DAI and 70% USDC (read on to see exactly how exit liquidity works).

+

B fills part of the remaining required liquidity (at a ratio of 90% DAI and 10% USDC) with 500 DAI and 50 USDC.

+

C fills part of the remaining required liquidity (at a ratio of 90% DAI and 10% USDC) with 100 DAI and 10 USDC.

+

D fills the rest of the required liquidity (at a ratio of 90% DAI and 10% USDC) with 300 DAI and 30 USDC.

+
By adding the remaining required liquidity, D has triggered Uniswap’s Add Liquidity order ...
+

The total Uniswap liquidity pooled by A,B,C and D is 1,000 DAI and 1,000 USDC.

+

After 543055 Blocks, the liquidity pool has earned 1,000 USDC and 1,000 DAI in Uniswap trading fees, bringing the total to 2,000 DAI and 2,000 USDC.

+
... B then triggers the removal action, and based on the fixed predetermined rules, the providers receive the following:
+

A receives 600 DAI and 1,400 USDC (at the Exit Ratio of 30% DAI and 70% USDC).

+

Based on how much they individually contributed, B, C and D receive their respective proportion of 1,400 DAI and 600 USDC (at the Exit Ratio of 70% DAI and 30% USDC).

+
+
+

Initial Liquidity Offering (ILO)

+

Initial Liquidity Offerings are a way for Ethereum-based startups to configure “Crafting”—i.e, Programmable Liquidity—rules to secure long term funding by providing Uniswap liquidity.

+
ILOs are helpful for three specific reasons:
+

Securing Initial Liquidity for AMMs with fixed inflation/liquidity staking

+

Providers can offer liquidity with fixed inflation without dumping on new holders. They also help new investors reduce slippage and become holders with a large amount of capital.

+

Disarming Sniper Bots

+

Sniper Bots track new low liquidity Uniswap pools for sizable capital before liquidity even comes in, making it (until now) impossible for startups to offer liquidity with low collateral.

+

Securing Long Term Locked Investors

+

Investors lock their funds for the long run.

+

How ILOs work:

+

Before distributing their tokens, startups can set crafting orders with fixed pre-values, adding the token and requesting the collateral required to fill the order. Investors provide that collateral, and if the startup chooses, investors get an Exit/Discount to mitigate the high risk.

+
Example
+

The token creator sets a Crafting order with low liquidity, e.g. 1,000,000 of the token and 1 ETH, with a 90% - 10% ratio, or even 1,000,000 of token and 0 ETH, with a 100% - 0% ratio (adding a pre-value of the token, if the liquidity pool is not open yet) for one year. Setting the Liquidity Exit/Discount 10%/20%, investors will receive at the end of the order 90%/80%.

+

In this case, investors invest their own Ethereum for a new token that is not already tradable. This entails a high level or risk, and so they are compensated by receiving a more significant portion of the liquidity at the end of the year; in this case, from 50% added to 170% received.

+
ILOs enable new Ethereum fundraising rules that solve liquidity issues in early stages, while also helping legitimate projects set Fixed Inflation. This empowers projects and investors in the long run.
+
UniFi DFO Tax:
+

The UniFi DFO earns via the Crafting function; 0.1% of the total Uniswap Pool Tokens in a Craft order is taxed and paid directly when a participant calls the remove function.

+
+
+

Release

+

The Release Of Crafting and ILOs is expected for early October 2020

+
+
+
+
+ ); + } +}); \ No newline at end of file diff --git a/spa/grimoire/grimUnifi.jsx b/spa/grimoire/grimUnifi.jsx new file mode 100644 index 0000000..9165182 --- /dev/null +++ b/spa/grimoire/grimUnifi.jsx @@ -0,0 +1,75 @@ +var GrimUnifi = React.createClass({ + requiredScripts: [ + 'spa/loader.jsx' + ], + + render() { + return ( +
+
+
+ +
+

The Grimoire - Decentralized Finance on top of Uniswap and the UniFi token

+
UniFi is a new Decentralized Flexible Organization (DFO) that researches and develops a responsible Decentralized Finance layer on top of Uniswap.
+
+
+
+
+
+ +
+

Basics

+

UniFi is a new Decentralized Flexible Organization (DFO) that researches and develops a responsible Decentralized Finance layer on top of Uniswap. Thanks to the DFOhub standard, UniFi dApps are entirely independent from any off-chain entity. The $UniFi voting token is a programmable equity of the UniFi DFO; $UniFi holders hold real equity of the protocol, and rule every part of its code and assets. More info here: dfohub.com

+
+
+

UniFi Token Distribution

+

The total supply of $UniFi is 88,888,888, which is initially distributed and Locked as follows:

+
    +
  1. - 36% (32,042,000) are locked in the NERV Wallet [0x25756f9C2cCeaCd787260b001F224159aB9fB97A] This is the DFOhub Operation' DFO wallet, funded by Fair Inflation.
  2. +
  3. - 40% (35,900,000) are locked in the UniFI's DFO wallet [0x2578aA454b29C15c8eEF62C972Ee1ff57CD99DEf]. This pays out the liquidity staking rewards. The active reward staking contract is [0xb266252Fd70D253b4330151A96694d35e94b846c]
  4. +
  5. - 16% (14,333,333) are locked in the DFOhub wallet (owned by $buidl holders) [0x5D40c724ba3e7Ffa6a91db223368977C522BdACD]
  6. +
+
+
+

UniFi Fair Inflation

+
A sustainable economic model for DFO-based startups to maintain value and fund operations | UniFi version
+

The original whitepaper of the first fair inflation mechanism was for buidl (https://github.com/b-u-i-d-l/fair-inflation-v2)

+

UniFi’s fair inflation will inflate the supply by 2% (1,788,500 $UniFi) over the first year via NERV (The DFOhub Team Operations' DFO)

+
Inflation events will occur once a day (every 6,300 ETH Blocks) across three Uniswap pairs, for a total of 4,900 $UniFi each event:
+
    +
  1. - Uniswap V2 $ETH/$UniFi (2695 $UniFi every day) - 55%
  2. +
  3. - Uniswap V2 $USDC/$UniFi (1470 $UniFi every day) - 30%
  4. +
  5. - Uniswap V2 $BUIDL/$UniFi (735 $UniFi every day) - 15%
  6. +
+

All functionalities related to this R&D will become available for every DFO as Optional Basic Functionalities, to accelerate the exploration of Programmable Equity R&D.

+
+
+

UniFi Liquidity Staking

+

$UniFi liquidity staking is available here: https://dapp.dfohub.com/?staking=0xb266252Fd70D253b4330151A96694d35e94b846c

+

The UniFi Liquidity Staking Mechanism is designed to reward those who lock up Uniswap V2 liquidity for the long term.

+

Staking will inflate the supply over the first year (if every tier is completely filled) by 918,000 $UniFi (1% of the supply).

+

The Five Year tier was filled by the team in an early test, and we won’t touch the rewards for three years. When they are unlocked and redeemed, 50% of the UniFi will be sent to the UniFi wallet and 50% to the NERV operations wallet.

+
+
+

UniFi Earning System

+

The UniFi DFO earn from:

+
    +
  1. - The uSD positive rebalance (the trading fees of Uniswap collateralized stablecoins)
  2. +
  3. - The 0.1% in Uniswap Pool Tokens taxed by crafting Programmable Liquidity
  4. +
+

As an on-chain company, UniFi’s value will be backed by these earnings, and by the core of Flexible Organizations, totally ruled in code and assets by tokens, without any chance of external manipulation.

+
+
+
+
+ ); + } +}); \ No newline at end of file diff --git a/spa/grimoire/grimuSD.jsx b/spa/grimoire/grimuSD.jsx new file mode 100644 index 0000000..d0574a3 --- /dev/null +++ b/spa/grimoire/grimuSD.jsx @@ -0,0 +1,105 @@ +var GrimuSD = React.createClass({ + requiredScripts: [ + 'spa/loader.jsx' + ], + + render() { + return ( +
+
+
+ +
+

The Grimoire - Unified Stable Dollar

+
uSD is a Stable Coin based on Uniswap Liquidity Pools Minted by the magic rainbow of Uniswap stablecoin pools. Backed by the power of the Unicorn, uSD is the most secure stablecoin ever. The only way it could be destabilized is if the entire stablecoin industry crashed. | Etherscan Uniswap
+
+
+
+
+
+ +
+

Basics

+

The aim of the Unified Stable Dollar (uSD) protocol is to build the most secure and resilient stablecoin on Ethereum—ever. Independent from any off-chain issuer, it is fortified against the risks inherent to all other stablecoins, and free of the anxiety that pervades the industry.

+

uSD achieves this unprecedented level of stability by collateralizing other stablecoins. If any of them lose value or fail, it can simply rebalance itself to leverage the security of the others. And to account for excess due to fees in their pools, it can rebalance itself in another way.

+

The only way uSD can be destabilized is if the entire stablecoin industry collapses.

+
uSD is backed by Uniswap’s (whitelisted) stablecoin liquidity pools.
+
Anyone can mint it by adding these stablecoins to those pools.
+

Example:

+

Mint 2x uSD by adding 1x Stablecoin A and 1x Stablecoin B

+
And by burning uSD, anyone can receive these stablecoins from those pools.
+

Example:

+

Burn 2x uSD and receive 1x Stablecoin A and 1x Stablecoin C

+
+
+

Rebalancing

+
Sometimes, collateralization is not enough, and uSD must rebalance in one of two ways.
+

DFO Debit

+

When a stablecoin loses value, the Uniswap Tier pools rebalance to an uneven disparity (≠ 50/50). If the stablecoin totally fails, the other stablecoins effectively pump in correlation.

+

DFO Debit resolves this issue on-chain by rebalancing uSD, creating debt which the UniFi DFO then pays off by minting UniFi. Let’s look at how this plays out, step by step:

+
    +
  1. 1 - A stablecoin collateralized by uSD loses value or fails altogether.
  2. +
  3. 2 - $UniFi holders vote to remove the tiers containing the failed stablecoin from the whitelist.
  4. +
  5. The uSD supply becomes grater than the supply of the collateralized pooled stablecoins.
  6. +
  7. 3 - To restore 1:1 equilibrium, anyone holding uSD can burn it to receive new UniFi, minted at a 20% discount of the uSD/UniFi Uniswap pool mid-price ratio.
  8. +
+
The goal of $UniFi holders, which aligns with their self-interest, is to ensure uSD’s security. Thus there is an economic disincentive to whitelist insecure stablecoins.
+

DFO Credit

+

As established, uSD is backed by Uniswap pool liquidity. This raises an issue; Uniswap pools earn 0.3% of trading fees. This could destabilize uSD by creating an excess of collateralized stablecoins in the pools.

+

DFO Credit, the second rebalancing function of the UniFi DFO, resolves this by removing that excess from the pools and sending it in the DFO wallet managed by $UniFi holders.

+

This is a long term economic incentive for the UniFi DFO to grow and invest credit in R&D.

+
+
+

Security and Emergency Strategies

+

The UniFi has a number of measures in place to ensure its security.

+

1 - uSD pool collateral is locked. Stored in an external smart contract, it can’t be touched even by the UniFi DFO, precluding voter fraud by bad actors.

+

2 - In the case of any bug or update, $UniFi holders can vote to pause the uSD smart contract. This prevents minting of new uSD or rebalancing of uSD, but holders will still be able to redeem it for the pooled stable coins, and thus revoke the collateral.

+

3 - Even if the uSD protocol fails, and even if the UniFi DFO votes to update uSD to an undesirable new version, uSD holders will still be able to interact with the old smart contract—until all collateral is revoked—as well as the new one.

+
+
+

Resilience, Decentralization and independency

+

uSD is the most resilient, secure and stable stablecoin in the industry. By taking advantage of Decentralized Finance on the top of Uniswap, a security layer with a decentralized core, it frees holders from dependence on censorship or centralized manipulation by states and stablecoin issuers. It resolves all risks that come with trusting the big stablecoin companies, like MakerDAO, Coinbase, Tether etc.

+

uSD is backed by a Decentralized Flexible Organization. $UniFi holders on the Ethereum network have 100% control of the code and Credit/Debit of the protocol. Nobody can stop or censor the UniFi-uSD protocol; for the first time, the Ethereum network doesn’t have to choose between stability and independence in a stablecoin; it can have both.

+
+ +
+

APIs and Documentation

+

To build on top of uSD and to interact with the dApp, you can find all of the documentation and APIs here: Documentation

+
+
+

Responsible DeFi Limits

+

Due to a Responible DeFi Approach, UniFi uSD is limited in its early stage to mint by:

+
    +
  1. - 500,000 uSD Mintable for the first month (untill block n 10941929)
  2. +
  3. - 2,000,000 uSD Mintable for the first two months (untill block n 11141929)
  4. +
  5. - 5,000,000 uSD Mintable for the first three months (untill block n 11341929)
  6. +
  7. - 10,000,000 uSD Mintable for the first four months (untill block n 11541929)
  8. +
  9. - 20,000,000 uSD Mintable for the first five months (untill block n 11741929)
  10. +
+
+
+
+
+ ); + } +}); \ No newline at end of file diff --git a/spa/grimoire/style.min.css b/spa/grimoire/style.min.css index 8721c7d..e69de29 100644 --- a/spa/grimoire/style.min.css +++ b/spa/grimoire/style.min.css @@ -1 +0,0 @@ -.swapBazar{width:100%;height:100%;position:relative;color:white}.swapBazar iframe{width:100%;height:100%;border:none}.swapBazar .floatingMenu{position:absolute;top:10%;left:10%}.swapBazar .floatingMenu .loader{margin:2%}.swapBazar .floatingMenu .tokensList{overflow-y:hidden;overflow-x:auto;width:100%;max-height:350px} diff --git a/spa/grimoire/style.scss b/spa/grimoire/style.scss index 1c1ff73..e69de29 100644 --- a/spa/grimoire/style.scss +++ b/spa/grimoire/style.scss @@ -1,25 +0,0 @@ -.swapBazar { - width: 100%; - height: 100%; - position: relative; - color: white; - iframe { - width: 100%; - height: 100%; - border: none; - } - .floatingMenu { - position: absolute; - top: 10%; - left: 10%; - .loader { - margin: 2%; - } - .tokensList { - overflow-y: hidden; - overflow-x: auto; - width: 100%; - max-height: 350px; - } - } -} \ No newline at end of file diff --git a/spa/grimoire/view.jsx b/spa/grimoire/view.jsx index 90b8a58..01394a5 100644 --- a/spa/grimoire/view.jsx +++ b/spa/grimoire/view.jsx @@ -1,8 +1,31 @@ var Grimoire = React.createClass({ requiredScripts: [ - 'spa/loader.jsx' + 'spa/loader.jsx', + 'spa/grimoire/grimuSD.jsx', + 'spa/grimoire/grimCrafting.jsx', + 'spa/grimoire/grimBazar.jsx', + 'spa/grimoire/grimUnifi.jsx' ], - + getDefaultSubscriptions() { + return { + 'ethereum/update' : () => this.forceUpdate() + } + }, + componentDidMount() { + if(!this.props.href) { + return; + } + var href = this.props.href; + setTimeout(function() { + var host = window.location.protocol; + host += "//"; + host += window.location.hostname; + window.location.port && (host += (":" + window.location.port)); + host +="/"; + host += href; + window.location.href = host; + }, 200); + }, render() { return (
@@ -11,14 +34,27 @@ var Grimoire = React.createClass({
-

Uniswap State Dollar

-
uSD is a Stable Coin based on Uniswap Liquidity Pools More

Here, you can mint uSD by adding liquidity to whitelisted Uniswap Stable Coin Pools or redeem anytime whitelisted Stable Coins by burning uSD.
+

The Grimoire

+
Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities, Token Indexes and NFTs (including ERC 1155 NFTs, thanks to ethArt V2) can now be swapped, on the new Bazaar DEX.
-
+
+
+ +
+ + + +
); } diff --git a/spa/index/controller.jsx b/spa/index/controller.jsx index f29df97..4edcb97 100644 --- a/spa/index/controller.jsx +++ b/spa/index/controller.jsx @@ -1,4 +1,13 @@ var IndexController = function (view) { var context = this; context.view = view; + + context.onSection = function onSection() { + var section = window.consumeAddressBarParam("section"); + if(window.location.hostname.indexOf(window.context.domainData.name) !== -1) { + section = window.location.hostname.split('.')[0]; + section = window.context.domainData.sections[section]; + } + section && context.view.sectionChange(section); + }; }; \ No newline at end of file diff --git a/spa/index/view.jsx b/spa/index/view.jsx index 6ace569..e3ecf61 100644 --- a/spa/index/view.jsx +++ b/spa/index/view.jsx @@ -3,24 +3,34 @@ var Index = React.createClass({ 'spa/loader.jsx' ], requiredModules: [ - 'spa/explainer' + 'spa/explainer', + 'spa/dappMenu' ], + getCustomLoader() { + return (
+ +

Welcome to the UniFi World

+
); + }, getDefaultSubscriptions() { return { - 'section/change': this.sectionChange + 'section/change': this.sectionChange, + 'visual/mode/toggle': this.toggleBoomerMode }; }, sectionChange(section, props) { var _this = this; ReactModuleLoader.load({ - modules : ['spa/' + section.firstLetterToLowerCase()], - callback: () => _this.setState({section: section.firstLetterToUpperCase(), props}) + modules: ['spa/' + section.firstLetterToLowerCase()], + callback: () => _this.setState({ section: section.firstLetterToUpperCase(), props }) }); }, + toggleBoomerMode() { + window.localStorage.setItem('boomerMode', !this.domRoot.hasClass('Boomer')); + this.forceUpdate(); + }, componentDidMount() { - var section = window.addressBarParams.section; - delete window.addressBarParams.section; - section && this.sectionChange(section); + this.controller.onSection(); }, render() { var props = {}; @@ -29,7 +39,7 @@ var Index = React.createClass({ props.props && Object.entries(props.props).forEach(entry => props[entry[0]] = entry[1]); delete props.props; return ( -
+
{React.createElement(window[props.section || 'Explainer'], props)}
); diff --git a/spa/loader.jsx b/spa/loader.jsx index 31f5952..42d2741 100644 --- a/spa/loader.jsx +++ b/spa/loader.jsx @@ -25,7 +25,7 @@ var Loader = React.createClass({ },*/ render() { return ( - + ); } }); \ No newline at end of file diff --git a/spa/stableCoin/controller.jsx b/spa/stableCoin/controller.jsx index e87772d..136a32e 100644 --- a/spa/stableCoin/controller.jsx +++ b/spa/stableCoin/controller.jsx @@ -3,16 +3,22 @@ var StableCoinController = function (view) { context.view = view; context.loadData = async function loadData() { + await window.loadEthereumStuff(context.view.oldStableCoin); + delete window.addressBarParams.useOldStableCoin; + context.view.forceUpdate(); context.loadPairs(); context.loadEconomicData(); + context.view.economicDataInterval = context.view.economicDataInterval || setInterval(context.loadEconomicData, window.context.refreshDataPollingInterval); }; context.loadEconomicData = async function loadEconomicData() { context.view.setState({ differences : await context.loadDifferences() }); context.view.setState({ totalSupply: await window.blockchainCall(window.stableCoin.token.methods.totalSupply) }); context.view.setState({ availableToMint: await window.blockchainCall(window.stableCoin.token.methods.availableToMint) }); + context.view.setState({myBalance : await context.getMyBalance()}); context.getTotalCoins(); context.calculatePriceInDollars(); + context.view.state && context.view.state.selectedPair && context.getBalance(context.view.state.selectedPair); }; context.loadDifferences = async function loadDifferences() { @@ -35,18 +41,35 @@ var StableCoinController = function (view) { index: pairs.length, address: pairAddress, pair: pair, - token0: await window.loadTokenInfos(await window.blockchainCall(pair.methods.token0), window.wethToken.options.address), - token1: await window.loadTokenInfos(await window.blockchainCall(pair.methods.token1), window.wethToken.options.address) + token0: await window.loadTokenInfos(await window.blockchainCall(pair.methods.token0)), + token1: await window.loadTokenInfos(await window.blockchainCall(pair.methods.token1)) }; pairData.name = pairData.token0.symbol + ' / ' + pairData.token1.symbol; + var reserves = await window.blockchainCall(pair.methods.getReserves); + reserves[0] = context.fromTokenToStable(pairData.token0.decimals, reserves[0]); + reserves[1] = context.fromTokenToStable(pairData.token1.decimals, reserves[1]); + var total = window.web3.utils.toBN(reserves[0]).add(window.web3.utils.toBN(reserves[1])).toString(); + total = window.fromDecimals(total, window.stableCoin.decimals, true); + total = parseFloat(total); + if(total < window.context.uSDPoolLimit) { + pairData.disabled = true; + } pairs.push(pairData); } - context.view.setState({ pairs, selectedPair: pairs[0], token0Approved: null, token1Approved: null }, function () { - context.checkApprove(pairs[0]); + context.view.setState({ pairs, selectedPair: context.firstNonDisabledPair(pairs), token0Approved: null, token1Approved: null }, function () { + context.checkApprove(context.view.state.selectedPair); context.getTotalCoins(); }); }; + context.firstNonDisabledPair = function firstNonDisabledPair(pairs) { + for(var pairData of pairs) { + if(!pairData.disabled) { + return pairData; + } + } + }; + context.getBalance = async function getBalance(selectedPair) { selectedPair.token0.balance = !window.walletAddress ? '0' : await window.blockchainCall(selectedPair.token0.token.methods.balanceOf, window.walletAddress); selectedPair.token1.balance = !window.walletAddress ? '0' : await window.blockchainCall(selectedPair.token1.token.methods.balanceOf, window.walletAddress); @@ -138,6 +161,7 @@ var StableCoinController = function (view) { token1Slippage = window.web3.utils.toBN(token1Value).sub(window.web3.utils.toBN(token1Slippage)).toString(); await window.blockchainCall(window.stableCoin.token.methods.mint, pairData.index, token0Value, token1Value, token0Slippage, token1Slippage); context.loadEconomicData(); + context.view.openSuccessMessage(`minted new ${window.stableCoin.symbol} tokens`); } catch (e) { var message = e.message || e; if (message.toLowerCase().indexOf('user denied') === -1) { @@ -176,6 +200,7 @@ var StableCoinController = function (view) { token1Slippage = window.web3.utils.toBN(token1Value).sub(window.web3.utils.toBN(token1Slippage)).toString(); await window.blockchainCall(window.stableCoin.token.methods.burn, pairData.index, supplyInPercentage, token0Slippage, token1Slippage); context.loadEconomicData(); + context.view.openSuccessMessage(`burnt your ${window.stableCoin.symbol} tokens`); } catch (e) { var message = e.message || e; if (message.toLowerCase().indexOf('user denied') === -1) { @@ -218,6 +243,7 @@ var StableCoinController = function (view) { token1Slippage = window.web3.utils.toBN(token1Value).sub(window.web3.utils.toBN(token1Slippage)).toString(); await window.blockchainCall(window.stableCoin.token.methods.rebalanceByCredit, pairData.index, poolAmount, token0Slippage, token1Slippage); context.loadEconomicData(); + context.view.openSuccessMessage(`rebalanced by credit the ${window.stableCoin.symbol}`); } catch (e) { var message = e.message || e; if (message.toLowerCase().indexOf('user denied') === -1) { @@ -271,6 +297,7 @@ var StableCoinController = function (view) { } await window.blockchainCall(window.stableCoin.token.methods.rebalanceByDebt, amount); context.loadEconomicData(); + context.view.openSuccessMessage(`rebalanced by debt the ${window.stableCoin.symbol}`); } catch (e) { var message = e.message || e; if (message.toLowerCase().indexOf('user denied') === -1) { @@ -279,6 +306,13 @@ var StableCoinController = function (view) { } }; + context.getMyBalance = async function getMyBalance() { + if(!window.walletAddress) { + return null; + } + return await window.blockchainCall(window.stableCoin.token.methods.balanceOf, window.walletAddress); + }; + context.calculateRebalanceByDebtReward = async function calculateRebalanceByDebtReward(amount) { amount = window.toDecimals(amount.split(',').join(''), window.stableCoin.decimals); return await window.blockchainCall(window.stableCoin.token.methods.calculateRebalanceByDebtReward, amount); @@ -289,7 +323,7 @@ var StableCoinController = function (view) { return; } var totalCoins = { - amount : '0', + balanceOf : '0', list : { } }; @@ -297,38 +331,48 @@ var StableCoinController = function (view) { var reserves = await window.blockchainCall(pairData.pair.methods.getReserves); reserves.poolBalance = parseInt(await window.blockchainCall(pairData.pair.methods.balanceOf, window.stableCoin.address)); var totalSupply = parseInt(await window.blockchainCall(pairData.pair.methods.totalSupply)); - var amount = reserves.poolBalance / totalSupply; - reserves.token0 = parseInt(reserves[0]) * amount; - reserves.token1 = parseInt(reserves[1]) * amount; + var balanceOf = reserves.poolBalance / totalSupply; + reserves.token0 = parseInt(reserves[0]) * balanceOf; + reserves.token1 = parseInt(reserves[1]) * balanceOf; reserves.token0 = window.numberToString(reserves.token0).split(',').join('').split('.')[0]; reserves.token1 = window.numberToString(reserves.token1).split(',').join('').split('.')[0]; reserves.token0InStable = context.fromTokenToStable(pairData.token0.decimals, reserves.token0); reserves.token1InStable = context.fromTokenToStable(pairData.token1.decimals, reserves.token1); - totalCoins.amount = window.web3.utils.toBN(reserves.token0InStable).add(window.web3.utils.toBN(reserves.token1InStable)).add(window.web3.utils.toBN(totalCoins.amount)).toString(); + totalCoins.balanceOf = window.web3.utils.toBN(reserves.token0InStable).add(window.web3.utils.toBN(reserves.token1InStable)).add(window.web3.utils.toBN(totalCoins.balanceOf)).toString(); totalCoins.list[pairData.token0.address] = totalCoins.list[pairData.token0.address] || { symbol: pairData.token0.symbol, name: pairData.token0.name, - amount : '0', + balanceOf : '0', address : pairData.token0.address, decimals: pairData.token0.decimals }; - totalCoins.list[pairData.token0.address].amount = window.web3.utils.toBN(reserves.token0InStable).add(window.web3.utils.toBN(totalCoins.list[pairData.token0.address].amount)).toString(); + totalCoins.list[pairData.token0.address].balanceOf = window.web3.utils.toBN(reserves.token0InStable).add(window.web3.utils.toBN(totalCoins.list[pairData.token0.address].balanceOf)).toString(); totalCoins.list[pairData.token1.address] = totalCoins.list[pairData.token1.address] || { symbol: pairData.token1.symbol, name: pairData.token1.name, - amount : '0', + balanceOf : '0', address : pairData.token1.address, decimals: pairData.token1.decimals }; - totalCoins.list[pairData.token1.address].amount = window.web3.utils.toBN(reserves.token1InStable).add(window.web3.utils.toBN(totalCoins.list[pairData.token1.address].amount)).toString(); + totalCoins.list[pairData.token1.address].balanceOf = window.web3.utils.toBN(reserves.token1InStable).add(window.web3.utils.toBN(totalCoins.list[pairData.token1.address].balanceOf)).toString(); } - var totalSupply = parseInt(context.view.state.totalSupply); - var amount = parseInt(totalCoins.amount); - var first = totalSupply < amount ? totalSupply : amount; - var second = totalSupply > amount ? totalSupply : amount; + var balanceOf = totalCoins.balanceOf; + var totalSupply = context.view.state.totalSupply; + totalSupply = parseInt(totalSupply); + balanceOf = parseInt(balanceOf); + var first = totalSupply < balanceOf ? totalSupply : balanceOf; + var second = totalSupply > balanceOf ? totalSupply : balanceOf; var percentage = (first / second) * 100; + percentage = parseInt(window.formatMoney(percentage, 0)); + balanceOf > totalSupply && (percentage = percentage === 200 ? 200 : percentage > 200 ? 201 : 200 - percentage); totalCoins.regularPercentage = window.numberToString(percentage).split(',').join('').split('.')[0]; totalCoins.healthPercentage = window.numberToString(percentage / 2).split(',').join('').split('.')[0]; + parseInt(totalCoins.regularPercentage) > 200 && (totalCoins.regularPercentage = '200+'); + parseInt(totalCoins.healthPercentage) > 100 && (totalCoins.healthPercentage = '100'); + if(isNaN(parseInt(totalCoins.regularPercentage)) || (balanceOf === 0 && totalSupply === 0)) { + totalCoins.regularPercentage = '100'; + totalCoins.healthPercentage = '50'; + } context.view.setState({totalCoins}); }; diff --git a/spa/stableCoin/view.jsx b/spa/stableCoin/view.jsx index f486ae9..f763342 100644 --- a/spa/stableCoin/view.jsx +++ b/spa/stableCoin/view.jsx @@ -1,7 +1,8 @@ var StableCoin = React.createClass({ requiredScripts: [ 'spa/banner.jsx', - 'spa/loader.jsx' + 'spa/loader.jsx', + 'spa/grimoire/grimuSD.jsx' ], requiredModules: [ 'spa/dappMenu' @@ -9,12 +10,29 @@ var StableCoin = React.createClass({ getDefaultSubscriptions() { return { 'ethereum/update': this.controller.loadData, - 'ethereum/ping': () => this.state && this.state.selectedPair && this.controller.checkApprove(this.state.selectedPair) + 'ethereum/ping': () => this.state && this.state.selectedPair && this.controller.checkApprove(this.state.selectedPair), + 'success/message' : this.openSuccessMessage } }, componentDidMount() { + this.oldStableCoin = this.props.oldStableCoin || window.consumeAddressBarParam("useOldStableCoin") !== undefined this.controller.loadData(); }, + componentWillUnmount() { + delete this.oldStableCoin; + this.economicDataInterval && window.clearInterval(this.economicDataInterval); + delete this.economicDataInterval; + }, + onActionChange(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + var value = e.currentTarget.value; + var _this = this; + _this.setState({ myBalance: null }, function () { + value === 'Burn' && _this.controller.getMyBalance().then(function (myBalance) { + _this.setState({ myBalance }); + }); + }); + }, onPairChange(e) { e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); var _this = this; @@ -77,7 +95,7 @@ var StableCoin = React.createClass({ } return (
-

Still available to Mint:

+

Mintable:

{window.fromDecimals(this.state.availableToMint, window.stableCoin.decimals)} {window.stableCoin.symbol}
); @@ -109,41 +127,78 @@ var StableCoin = React.createClass({ var target = e.currentTarget; _this.onTypeTimeout && window.clearTimeout(_this.onTypeTimeout); _this.onTypeTimeout = setTimeout(function () { - _this.controller.calculateRebalanceByDebtReward(target.value).then(function(result) { + _this.controller.calculateRebalanceByDebtReward(target.value).then(function (result) { _this.debtReward.innerHTML = window.fromDecimals(result, window.dfo.decimals); }); }, window.context.typeTimeout); }, + toggleGrimoire(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.setState({ grimoire: !(this.state && this.state.grimoire) }); + }, + closeSuccessMessage(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.successMessageCloseTimeout && window.clearTimeout(this.successMessageCloseTimeout); + this.setState({successMessage : null}); + }, + openSuccessMessage(successMessage) { + this.closeSuccessMessage(); + var _this = this; + _this.setState({successMessage}, function() { + _this.successMessageCloseTimeout = setTimeout(function() { + //_this.closeSuccessMessage(); + }, 4000); + }); + }, render() { return (
-
+
+
+ + {this.state && this.state.grimoire && } + {(!this.state || !this.state.grimoire) && } + +
+
+ {window.stableCoin && window.stableCoin.name && window.stableCoin.symbol &&
-

Uniswap State Dollar

-
uSD is a Stable Coin based on Uniswap Liquidity Pools More

Here, you can mint uSD by adding liquidity to whitelisted Uniswap Stable Coin Pools or redeem anytime whitelisted Stable Coins by burning uSD.
+

{window.stableCoin.name.firstLetterToUpperCase()}

+
{window.stableCoin.symbol} is a Stable Coin based on Uniswap Liquidity Pools
Here, you can mint {window.stableCoin.symbol} by adding liquidity to whitelisted Uniswap Stable Coin Pools or redeem anytime whitelisted Stable Coins by burning {window.stableCoin.symbol}. | Etherscan Uniswap
-
- {!this.state || !this.state.selectedPair && } +
} + {false && this.state && this.state.successMessage &&
+ X +

+ You have successfully {this.state.successMessage}! +

+
} + {(!this.state || !this.state.selectedPair) && } {this.state && this.state.selectedPair &&
- - this.actionSelect = ref} onChange={this.onActionChange}> + {!this.oldStableCoin && }

{window.stableCoin.symbol}

-
+
@@ -162,6 +217,7 @@ var StableCoin = React.createClass({ {window.walletAddress &&
Max Balance: {window.fromDecimals(this.state.selectedPair.token1.balance, this.state.selectedPair.token1.decimals)} {this.state.selectedPair.token1.symbol}
}

for this.stableCoinOutput = ref}>0{'\u00a0'}{window.stableCoin.symbol}

+ {window.walletAddress && this.state && this.state.myBalance && this.actionSelect && this.actionSelect.value === 'Burn' &&
Balance: {window.fromDecimals(this.state.myBalance, window.stableCoin.decimals)}{'\u00a0'}{window.stableCoin.symbol}
} {window.walletAddress && (!this.state.token0Approved || this.state.token1Approved) && (this.state.approving === undefined || this.state.approving === null) && Approve {this.state.selectedPair.token0.symbol}} {window.walletAddress && this.state.token0Approved && !this.state.token1Approved && (this.state.approving === undefined || this.state.approving === null) && Approve {this.state.selectedPair.token1.symbol}} {this.state.approving !== undefined && this.state.approving !== null && } @@ -177,29 +233,29 @@ var StableCoin = React.createClass({
Supply:
{window.fromDecimals(this.state.totalSupply, window.stableCoin.decimals)} {window.stableCoin.symbol}
} - {this.renderAvailableToMint()} {this.state && this.state.totalCoins &&
Collateral:
-
{window.fromDecimals(this.state.totalCoins.amount, window.stableCoin.decimals)} S.C.
+
{window.fromDecimals(this.state.totalCoins.balanceOf, window.stableCoin.decimals)} S.C.
{this.state.toggleTotalCoins &&
    {Object.values(this.state.totalCoins.list).map(it =>
  • - {window.fromDecimals(it.amount, window.stableCoin.decimals)} + {window.fromDecimals(it.balanceOf, window.stableCoin.decimals)} {'\u00a0'} {it.symbol}
  • )}
}
} - {window.walletAddress && this.state && this.state.totalCoins &&
+ {this.renderAvailableToMint()} + {this.state && this.state.totalCoins &&

Health:

-
+
} - {window.walletAddress && this.state && this.state.pairs && this.state.totalCoins && this.state.differences && (this.state.differences[0] !== '0' || this.state.differences[1] !== '0') &&
+ {window.walletAddress && this.state && this.state.pairs && this.state.totalCoins && this.state.differences && (parseInt(this.state.totalCoins.regularPercentage) > 103 || parseInt(this.state.totalCoins.regularPercentage) < 97) &&

Rebalance

- {parseInt(this.state.totalCoins.regularPercentage) < 97 &&
+ {parseInt(this.state.totalCoins.regularPercentage) > 103 &&
}
} - {parseInt(this.state.totalCoins.regularPercentage) > 101 &&
+ {parseInt(this.state.totalCoins.regularPercentage) < 85 &&
} -

This protocol is built using a Responsable DeFi approach. But it's new, so use it at your own risk and remember, in Ethereum transactions are irreversible.

+

This protocol is built using a Responsible DeFi approach. But it's new, so use it at your own risk and remember, in Ethereum transactions are irreversible.

} + {this.state && this.state.grimoire && }
); } diff --git a/spa/swapBazar/controller.jsx b/spa/swapBazar/controller.jsx index cab97c8..8d5e1df 100644 --- a/spa/swapBazar/controller.jsx +++ b/spa/swapBazar/controller.jsx @@ -4,13 +4,254 @@ var SwapBazarController = function (view) { context.oldDfoDeployedEvent = "DFODeployed(address_indexed,address)"; context.dfoDeployedEvent = "DFODeployed(address_indexed,address_indexed,address,address)"; + context.proxyChangedEvent = "ProxyChanged(address)"; + + context.blockSearchSize = 40000; + context.dfoDeployedEvent = "DFODeployed(address_indexed,address)"; + context.newDfoDeployedEvent = "DFODeployed(address_indexed,address_indexed,address,address)"; context.loadData = async function loadData() { - context.view.setState({tokensList : null}); - var log = window.getDFOLog({ - event : context.dfoDeployedEvent, - topics : [(await window.dfo.proxy).options.allAddresses.map(it => window.web3.utils.sha3(window.web3.utils.toChecksumAddress(it)))] + await window.loadEthereumStuff(); + context.view.setState({inputToken : null, outputToken : null, inputPrice : null, outputPrice: null, uniswap: null}); + try { + context.view.setState({ + tokensList: { + "Prog. Equities": (await window.AJAXRequest(window.context.programmableEquitiesURL)).tokens.map(it => it.chainId === window.networkId && it), + "Tokens": (await window.AJAXRequest(window.context.uniswapTokensURL)).tokens.map(it => it.chainId === window.networkId && it), + Indexes: (await window.AJAXRequest(window.context.indexesURL)).tokens.map(it => it.chainId === window.networkId && it) + } + }); + } catch (e) { + await context.loadDataOnChain(); + } + context.loadLogos(); + context.readAddressBarParams(); + }; + + context.loadLogos = async function loadLogos() { + if(!context.view.state || !context.view.state.tokensList) { + return; + } + var tokensList = context.view.state.tokensList; + var keys = Object.keys(tokensList); + for(var key of keys) { + if(key === 'Indexes') { + continue; + } + var tokens = tokensList[key]; + for(var i = 0; i < tokens.length; i++) { + var token = tokensList[key][i]; + if(token === true || token === false) { + continue; + } + token.logoURI = token.logoURI || window.context.trustwalletImgURLTemplate.format(window.web3.utils.toChecksumAddress(token.address)); + try { + await window.AJAXRequest(token.logoURI); + if(!context.view.mounted) { + return; + } + } catch(e) { + token.logoURI = 'assets/img/default-logo.png' + } + tokensList[key][i] = token; + context.view.setState({tokensList}); + } + } + }; + + context.readAddressBarParams = async function readAddressBarParams() { + var token0 = window.addressBarParams.inputCurrency; + var token1 = window.addressBarParams.outputCurrency; + var uniswap = window.addressBarParams.action; + delete window.addressBarParams.token0; + delete window.addressBarParams.token1; + delete window.addressBarParams.action; + if(!token0 && !token1) { + return; + } + token0 && (token0 = window.web3.utils.toChecksumAddress(token0)); + token1 && (token1 = window.web3.utils.toChecksumAddress(token1)); + token1 === token0 && (token1 = undefined); + uniswap = token1 ? uniswap : undefined; + var selection = function selection(tokenAddress) { + if(!tokenAddress) { + return; + } + var keys = Object.keys(context.view.state.tokensList); + for(var key of keys) { + var tokens = context.view.state.tokensList[key]; + for(var selected = 0; selected < tokens.length; selected++) { + if(window.web3.utils.toChecksumAddress(tokens[selected].address) === tokenAddress) { + return { + key, + selected, + token: tokens[selected] + } + } + } + } + }; + var setState = async function setState(tokenName, tokenAddress) { + if(!tokenAddress) { + return; + } + var find = selection(tokenAddress); + if(!find) { + return; + } + var tokenPrice = tokenName + "Price"; + tokenName += "Token"; + var state = {}; + state[tokenName] = find.token; + state[tokenPrice] = await context.calculatePriceInDollars(state[tokenName]); + delete find.token; + context.view.setState(state, function() { + context.view[tokenName] && context.view[tokenName].setState(find); + }); + }; + await setState("input", token0); + await setState("output", token1); + uniswap && context.view.setState({uniswap}); + }; + + context.loadDataOnChain = async function loadDataOnChain() { + var dfoHub = await window.loadDFO(window.getNetworkElement("dfoAddress")); + context.dfoHubAddresses = dfoHub.options.allAddresses; + context.list = { + dfoHub: { + key: 'dfoHub', + token: await window.loadTokenInfos(await window.blockchainCall(dfoHub.methods.getToken), undefined, true) + } + }; + context.alreadyLoaded = {}; + await context.loadEvents(); + delete context.alreadyLoaded; + context.view.setState({ tokensList: null }); + + var programmableEquities = Object.values(context.list).map(it => it.token); + var uniswapTokens = await context.loadUniswapTokens(programmableEquities); + var indexes = {}; + + for (var token of uniswapTokens) { + await window.loadUniswapPairs(token, indexes); + } + + for (var token of programmableEquities) { + await window.loadUniswapPairs(token, indexes); + } + + await context.recursiveLoadPair(indexes); + + var tokensList = { + "Prog. Equities": programmableEquities, + "Tokens": uniswapTokens, + Indexes: Object.values(indexes) + }; + + context.view.setState({ + tokensList }); - console.log(log); + }; + + context.recursiveLoadPair = async function recursiveLoadPair(globalIndex, localIndex) { + localIndex = localIndex || globalIndex; + if (Object.keys(localIndex).length === 0) { + return; + } + var indexes = {}; + for (var pair of Object.values(localIndex)) { + await window.loadUniswapPairs(pair.address, indexes); + } + Object.entries(indexes).forEach(entry => globalIndex[entry[0]] = entry[1]); + await context.recursiveLoadPair(globalIndex, indexes); + } + + context.loadUniswapTokens = async function loadUniswapTokens(except) { + except = except || []; + var uniwapTokens = []; + var tokens = (await window.AJAXRequest(window.context.uniwsapOfficialTokensList)).tokens; + for (var token of tokens) { + if (window.networkId !== token.chainId) { + continue; + } + uniwapTokens.push({ + key: window.web3.utils.toChecksumAddress(token.address), + address: window.web3.utils.toChecksumAddress(token.address), + name: token.name, + symbol: token.symbol, + decimals: window.numberToString(token.decimals), + logo: token.icon + }); + } + return uniwapTokens; + }; + + context.contains = function contains(list, address) { + for (var element of list) { + if (window.web3.utils.toChecksumAddress(element.address) === window.web3.utils.toChecksumAddress(address)) { + return true; + } + } + return false; + }; + + context.loadEvents = async function loadEvents(topics, toBlock, lastBlockNumber) { + if (toBlock === window.getNetworkElement("deploySearchStart")) { + return; + } + lastBlockNumber = lastBlockNumber || await web3.eth.getBlockNumber(); + toBlock = toBlock || lastBlockNumber; + var fromBlock = toBlock - context.blockSearchSize; + var startBlock = window.getNetworkElement("deploySearchStart"); + fromBlock = fromBlock > startBlock ? startBlock : toBlock; + var newEventLogs = await context.getLogs(fromBlock, toBlock, context.newDfoDeployedEvent); + var oldEventLogs = await context.getLogs(fromBlock, toBlock, context.dfoDeployedEvent); + (newEventLogs.length > 0 || oldEventLogs.length > 0) && setTimeout(() => { + try { + context.view.forceUpdate(); + } catch (e) { + } + }); + setTimeout(() => context.loadEvents(topics, fromBlock, lastBlockNumber)); } + + context.getLogs = async function getLogs(fromBlock, toBlock, event) { + var logs = await window.getDFOLogs({ + address: context.dfoHubAddresses, + event, + fromBlock: '' + fromBlock, + toBlock: '' + toBlock + }); + for (var log of logs) { + if (context.alreadyLoaded[log.data[0].toLowerCase()]) { + continue; + } + context.alreadyLoaded[log.data[0].toLowerCase()] = true; + var key = log.blockNumber + '_' + log.id; + var dFO = await window.loadDFO(log.data[0]); + !context.list[key] && (context.list[key] = { + key, + startBlock: log.blockNumber, + token: await window.loadTokenInfos(await window.blockchainCall(dFO.methods.getToken), undefined, true) + }); + } + return logs; + }; + + context.getLatestSearchBlock = function getLatestSearchBlock() { + return (context.list && Object.keys(context.list).length > 0 && Math.max(...Object.keys(context.list).map(it => parseInt(it.split('_')[0])))) || window.getNetworkElement('deploySearchStart'); + }; + + context.calculatePriceInDollars = async function calculatePriceInDollars(token) { + var ethereumPrice = await window.getEthereumPrice(); + try { + var priceInDollars = window.fromDecimals((await window.blockchainCall(window.uniswapV2Router.methods.getAmountsOut, window.toDecimals('1', token.decimals), [token.address, window.wethAddress]))[1], 18, true); + priceInDollars = parseFloat(priceInDollars) * ethereumPrice; + priceInDollars = window.numberToString(priceInDollars); + var priceString = window.formatMoney(priceInDollars, 4); + return priceString === '0' ? priceInDollars : priceString; + } catch (e) { + return "notFound"; + } + }; }; \ No newline at end of file diff --git a/spa/swapBazar/style.min.css b/spa/swapBazar/style.min.css index 8721c7d..ec747fa 100644 --- a/spa/swapBazar/style.min.css +++ b/spa/swapBazar/style.min.css @@ -1 +1 @@ -.swapBazar{width:100%;height:100%;position:relative;color:white}.swapBazar iframe{width:100%;height:100%;border:none}.swapBazar .floatingMenu{position:absolute;top:10%;left:10%}.swapBazar .floatingMenu .loader{margin:2%}.swapBazar .floatingMenu .tokensList{overflow-y:hidden;overflow-x:auto;width:100%;max-height:350px} +null \ No newline at end of file diff --git a/spa/swapBazar/style.scss b/spa/swapBazar/style.scss index 1c1ff73..e69de29 100644 --- a/spa/swapBazar/style.scss +++ b/spa/swapBazar/style.scss @@ -1,25 +0,0 @@ -.swapBazar { - width: 100%; - height: 100%; - position: relative; - color: white; - iframe { - width: 100%; - height: 100%; - border: none; - } - .floatingMenu { - position: absolute; - top: 10%; - left: 10%; - .loader { - margin: 2%; - } - .tokensList { - overflow-y: hidden; - overflow-x: auto; - width: 100%; - max-height: 350px; - } - } -} \ No newline at end of file diff --git a/spa/swapBazar/uniswapTokenPicker.jsx b/spa/swapBazar/uniswapTokenPicker.jsx new file mode 100644 index 0000000..0b395b5 --- /dev/null +++ b/spa/swapBazar/uniswapTokenPicker.jsx @@ -0,0 +1,99 @@ +var UniswapTokenPicker = React.createClass({ + getDefaultSubscriptions() { + return { + 'ethereum/update' : () => this.setState({key: null, selected : null}) + }; + }, + onSectionChange(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + var key = e.currentTarget.dataset.key; + var _this = this; + this.setState({ key, selected: null }, function () { + _this.props.onChange && setTimeout(() => _this.props.onChange(null)); + }); + }, + close(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.setState({ opened: null }); + }, + open(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + var _this = this; + var oldTarget = e.currentTarget; + this.setState({ opened: true }, function () { + _this.opened && (_this.opened.onblur = _this.opened.onblur || function onblur(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + e.relatedTarget && e.relatedTarget !== oldTarget && e.relatedTarget.click(); + e.relatedTarget && e.relatedTarget !== oldTarget && _this.opened && _this.opened.focus(); + (!e.relatedTarget || (e.relatedTarget !== oldTarget && !e.relatedTarget.dataset.key)) && _this.setState({ opened: null }); + }) && _this.opened.focus(); + }); + }, + onClick(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + var _this = this; + this.setState({ opened: null, key: this.getKey(), selected: parseInt(e.currentTarget.dataset.index) }, function () { + _this.props.onChange && setTimeout(() => _this.props.onChange(_this.props.tokensList[_this.state.key][_this.state.selected])); + }); + }, + getKey() { + var key = null; + try { + key = (this.state && this.state.key) || Object.keys(this.props.tokensList)[0]; + } catch (e) { + } + return key; + }, + renderOpened() { + var _this = this; + var thisKey = this.getKey(); + return (
this.opened = ref}> +
+ X +
+
+
+ {this.props.tokensList && Object.keys(this.props.tokensList).map(key =>
  • + {key} +
  • )} +
    +
    + {thisKey &&
    + {this.props.tokensList[thisKey].map((it, i) => { + if (!it) { + return; + } + return (
  • + {this.renderInput(it, this.onClick, i)} +
  • ); + })} +
    } +
    ); + }, + renderInput(it, onClick, i) { + var key = this.getKey(); + return ( + {key !== "Indexes" && } +

    {it.symbol}

    +
    ); + }, + renderClosed() { + var selected = undefined; + try { + selected = this.props.tokensList[this.state.key][this.state.selected]; + } catch (e) { + } + return (
    + {selected && this.renderInput(selected, this.open)} + {!selected && Select} +
    ); + }, + render() { + return ( +
    + {this.state && this.state.opened && this.renderOpened()} + {this.state && this.state.opened &&
    } + {(!this.state || !this.state.opened) && this.renderClosed()} +
    ); + } +}); \ No newline at end of file diff --git a/spa/swapBazar/view.jsx b/spa/swapBazar/view.jsx index 7e45e81..1a2b38e 100644 --- a/spa/swapBazar/view.jsx +++ b/spa/swapBazar/view.jsx @@ -1,6 +1,8 @@ var SwapBazar = React.createClass({ requiredScripts: [ - 'spa/loader.jsx' + 'spa/loader.jsx', + 'spa/swapBazar/uniswapTokenPicker.jsx', + 'spa/grimoire/grimBazar.jsx' ], getDefaultSubscriptions() { return { @@ -8,36 +10,123 @@ var SwapBazar = React.createClass({ } }, componentDidMount() { + this.mounted = true; this.controller.loadData(); }, - onClick(e) { + componentWillUnmount() { + delete this.mounted; + }, + openUniswap(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + if (e.currentTarget.className.toLowerCase().indexOf('disabled') !== -1) { + return; + } + var uniswap = e.currentTarget.dataset.action; + var _this = this; + this.setState({ + uniswap: null + }, function () { + _this.setState({ uniswap }); + }); + }, + closeUniswap(e) { + e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.setState({ uniswap: null }); + }, + onToken(token, tokenName) { + var otherTokenPrice = (tokenName === 'input' ? 'output' : 'input') + 'Price'; + var otherTokenName = (tokenName === 'input' ? 'output' : 'input') + 'Token'; + var otherToken = this.state && this.state[otherTokenName]; + var tokenPrice = tokenName + 'Price'; + tokenName += "Token"; + var state = {}; + state[tokenName] = token; + state[tokenPrice] = null; + if (token && otherToken && otherToken.address === token.address) { + state[otherTokenName] = null; + state[otherTokenPrice] = null; + this[otherTokenName].setState({ key: null, selected: null }); + } + var _this = this; + this.setState(state, function () { + if ((!_this.state.inputToken || !_this.state.outputToken) && _this.state.uniswap) { + _this.setState({ uniswap: null }); + } + if(!token) { + return; + } + _this.controller.calculatePriceInDollars(token).then(function(priceInDollars) { + var state = {}; + state[tokenPrice] = priceInDollars; + _this.setState(state); + }); + }); + }, + toggleGrimoire(e) { e && e.preventDefault && e.preventDefault(true) && e.stopPropagation && e.stopPropagation(true); + this.setState({ grimoire: !(this.state && this.state.grimoire) }); }, - renderTokenList(type) { - return([ -

    {type}:

    , -
      - {this.state.tokensList.map((it, i) =>
    • - {it.name} -
    • )} -
    - ]); + renderUniswapLink() { + return window.context[this.state.uniswap === 'swap' ? "uniswapDappLinkTemplate" : "uniswapDappLinkTemplatePool"].format(this.state.uniswap, this.state.inputToken.address, this.state.outputToken.address, window.localStorage.boomerMode === 'true' ? 'light' : 'dark'); + }, + componentDidUpdate() { + var _this = this; + _this.state && _this.state.uniswap && _this.uniswapLoader && setTimeout(function() { + $(_this.uniswapLoader).css('display', 'none'); + }, 2000); }, render() { - return (
    - {} -
    -

    Tokens list

    - {!this.state || !this.state.tokensList &&
    - Loading... -
    } - {this.state && this.state.tokensList &&
    - {this.renderTokenList("From")} -
    } - {this.state && this.state.tokensList &&
    - {this.renderTokenList("To")} -
    } + return (
    + +
    +
    + + {this.state && this.state.grimoire && } + {(!this.state || !this.state.grimoire) && } + +
    +
    +
    +
    + +
    +

    The Bazar

    +
    Ancient black magic is unleashing the true power of the Unicorn. Programmable Equities, Token Indexes and NFTs (including ERC 1155 NFTs, thanks to ethArt V2) can now be swapped, on the new Bazaar DEX.
    +
    +
    + {this.state && this.state.uniswap && this.state.inputToken && this.state.outputToken && +
    + X + +
    this.uniswapLoader = ref} className="ArrivaUniswap"> + +
    +
    } + {(!this.state || !this.state.tokensList) && } + {this.state && this.state.tokensList &&
    +
    +
    +
    +
    From
    + +
    To
    + +
    +
    + Swap

    + Add Liquidity + Remove Liquidity +

    Select Tiers to Swap or Manage Liquidity

    +
    +
    } + {this.state && this.state.grimoire && }
    ); } }); \ No newline at end of file