Contract 0xa623b2DD931C5162b7a0B25852f4024Db48bb1A0 3

Contract Overview

Balance:
3,593.237955880635982346 Ether
Txn Hash Method
Block
From
To
Value
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c813Transfer93139072021-09-18 11:22:361 hr 18 mins ago0x722246643c7bb3d15ccef7e72fc5f90e53b9f457 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000154361001 1.000000009
0x298c9d07edf52561f331fdbf00b550b056b2b664482ea016c1019250de5da125Upgrade By ETH93138902021-09-18 11:18:201 hr 23 mins ago0x722246643c7bb3d15ccef7e72fc5f90e53b9f457 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a01 Ether0.000067958 1.000000009
0xa9c36f5c8349ab5de3bf6108682d2dcc69899a3d40cfd625de1543da70bb0431Upgrade By ETH93093252021-09-17 16:15:3120 hrs 25 mins ago0x2a54827f411e7080c1b51dc2d5f53b90eb6d6ddc IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.1 Ether0.000067958 1.000000009
0x68c27fcccd3dcf0834e8ce317434fd3f3aebe1dd4dd0753ff64da6bf8ce455cfUpgrade By ETH93033172021-09-16 15:10:421 day 21 hrs ago0x8441a85c00dce4bdff7bf4aede08efe630a9e921 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a01 Ether0.000067958001 1.000000019
0xe4f68b67cac0c5b8449b11d48cf808372b41c53a3df55ce8d9a28059e6a6d0e2Upgrade By ETH92975582021-09-15 15:09:052 days 21 hrs ago0xf6918e78db105a457e614ca23906361919221f69 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a01 Ether0.000067958001 1.000000029
0x97898fbf92f29b1d9aa71acedf1ebc5de1dd23fa4122c4b54dc071d55a5a5173Upgrade By ETH92975372021-09-15 15:03:492 days 21 hrs ago0xb4558718acd35b2f2bc21ad1a96fbe0e392d18ae IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a03 Ether0.000067958001 1.000000015
0x09c83582a2f8e2a7309b735f873f4d6ddfae266787586d93e775c9ece3563f6bTransfer92947492021-09-15 3:26:063 days 9 hrs ago0x795e4a946f39f109cfa962f168b1ae9b4da56e99 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000232326001 1.500000009
0xac3e160c242b5af758752467116e78787382a663d989999930b1576575f83b89Downgrade To ETH92943172021-09-15 1:38:023 days 11 hrs ago0x595823f9d3980520da19dec31d81530ca91d8b5a IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000141868001 1.000000008
0xc387e6a92786dca8b704293d05ee61434324bbfe00e27e59f33ded3f1b7832f3Upgrade By ETH92942982021-09-15 1:33:173 days 11 hrs ago0x595823f9d3980520da19dec31d81530ca91d8b5a IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.1 Ether0.000050858 1.000000008
0x6f41476d827a8b879730bb2c5dca7435afcf90c63f7eb6b6c78a1653e5725904Upgrade By ETH92941852021-09-15 1:05:003 days 11 hrs ago0x595823f9d3980520da19dec31d81530ca91d8b5a IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.1 Ether0.000067958 1.000000009
0x6b3c58107510151677f33bff0eb3c7dcf1740db7d1613e7e427632065811a964Downgrade To ETH92917252021-09-14 14:48:273 days 21 hrs ago0xa9c5bae593eb9d276dbc39e8b79710ef77799156 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000137080001 1.000000012
0xc6cff1264b1ebb075da07c7a206fd76c1d9327e477daf1b8530c7a9edd881864Upgrade By ETH92916802021-09-14 14:37:093 days 22 hrs ago0xa9c5bae593eb9d276dbc39e8b79710ef77799156 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.009 Ether0.000067958 1.00000001
0xe8f55f0b6d0b6bcb0da5d635fd1220b0df8bb22dfedbba32e40866ed4f5c0ff8Upgrade By ETH92916242021-09-14 14:23:083 days 22 hrs ago0xb4d6b7757d88ba7ebcb6663e91e98fa352c53e12 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.3 Ether0.000067958 1.000000013
0x1c7a6d41b9b04b462c37ee859a91164d7bbf63b459588a15172f3ec9c7064961Upgrade By ETH92900532021-09-14 7:49:404 days 4 hrs ago0x3c1be1d5851fff752e77f21727936916298610c9 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.002 Ether0.000050858 1.000000011
0x9a4b76322b7be9e88a5e47f885512075a5d6653546b40cdde7cc4d76fefd22ebUpgrade By ETH92900272021-09-14 7:43:084 days 4 hrs ago0x7032e08ace66212a9136ddfffd7b930cc0386b5a IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.005 Ether0.000067958 1.000000011
0x9d3025f1d312f7c85590cab55c19fa5a791b93954e9d84fb0e1ef1a034095258Upgrade By ETH92900142021-09-14 7:39:514 days 5 hrs ago0xc5fe457b170c5af74e10bdfac61fadf5bc724263 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.005 Ether0.000067958 1.000000012
0xd3a4cc7f9406ea8b2f3bc5efde1b04bacc1870b4ff39116e396fac80ef65d0fdTransfer92887902021-09-14 2:33:254 days 10 hrs ago0xe8ae7b4b4d531b8de60f262279c2bba840df5b63 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000154884001 1.000000008
0x13e43c2c1387ec43919b528a6aa2efbc61665676acbecf5ac4cecc5bc400db5fUpgrade By ETH92887872021-09-14 2:32:404 days 10 hrs ago0xe8ae7b4b4d531b8de60f262279c2bba840df5b63 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.005 Ether0.000050858 1.000000008
0x426d937b350e2a3ebdc6a558453c559fe7ecc3642ed0af65cff3be3460d2e384Upgrade By ETH92847622021-09-13 9:44:175 days 2 hrs ago0x88970e424aab155d11f1176a46e79a4f5355e1da IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.03 Ether0.000050858001 1.000000035
0x9fd10e8faecf2e6be99d52810ca5e68c747d714c90dc68b0c8445d562f248139Upgrade By ETH92847512021-09-13 9:41:315 days 2 hrs ago0xa744c3d890502e999c95a03e3685d4df3e74ab2c IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.03 Ether0.000050858001 1.000000039
0xbc794a424a4c82919d093b81095ec35a302c19e4cdbc038d442c1cddd8bc3b23Upgrade By ETH92847342021-09-13 9:37:155 days 3 hrs ago0x6dc3022d0ba376753d4f04ed5b4940394e35ca53 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.03 Ether0.000067958003 1.000000045
0xd99fb24a54b385e2c96e1e1bf609de740bd0ff35e261299b1ac54ce21e5855daUpgrade By ETH92847272021-09-13 9:35:305 days 3 hrs ago0x5ba25fd7e56ed682dccb2a569d24bb8bf84ec075 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.03 Ether0.000050858002 1.000000047
0xff2f0f72e4a111e3136a305e3d2d1d288bc479c8ec86f6d07978b0f9b24786f6Upgrade By ETH92847162021-09-13 9:32:455 days 3 hrs ago0x361bbb59f81170a7aa6cef4b9fcf3bf54ddc2c7c IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.04 Ether0.000067958003 1.000000058
0xce5edeabedf3a1aa4d9124462d0f551dd8721a6aad803142749234c1f38626e0Upgrade By ETH92847002021-09-13 9:28:455 days 3 hrs ago0x71884b2b9b5cb49bb5feb9c0fe4e6b01ad72dc56 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00.006 Ether0.000050858002 1.000000041
0xa824784ae9c9ef6ff74719d9b54661d3332e17aaee38b95c72554c5b6794f553Downgrade To ETH92845212021-09-13 8:43:565 days 3 hrs ago0x658e1b019f2f30c8089a9ae3ae5820f335bd9ce4 IN  0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether0.000137080001 1.000000012
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x1820a4b7618bde71dce8cdc73aab6c95905fad240 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0x32e0ecb72c1ddd92b007405f8102c1556624264d 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0x32e0ecb72c1ddd92b007405f8102c1556624264d 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x32e0ecb72c1ddd92b007405f8102c1556624264d0 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xf4c5310e51f6079f601a5fb7120bc72a70b96e2a 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0xf4c5310e51f6079f601a5fb7120bc72a70b96e2a0 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0xed5b5b32110c3ded02a07c8b8e97513fafb883b60 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x1820a4b7618bde71dce8cdc73aab6c95905fad240 Ether
0x389348b6fed8757d5a1adeae710be154091cbfdcbda33374c09cb8faf195c81393139072021-09-18 11:22:361 hr 18 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0x298c9d07edf52561f331fdbf00b550b056b2b664482ea016c1019250de5da12593138902021-09-18 11:18:201 hr 23 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x1820a4b7618bde71dce8cdc73aab6c95905fad240 Ether
0x298c9d07edf52561f331fdbf00b550b056b2b664482ea016c1019250de5da12593138902021-09-18 11:18:201 hr 23 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0x298c9d07edf52561f331fdbf00b550b056b2b664482ea016c1019250de5da12593138902021-09-18 11:18:201 hr 23 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0xa9c36f5c8349ab5de3bf6108682d2dcc69899a3d40cfd625de1543da70bb043193093252021-09-17 16:15:3120 hrs 25 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x1820a4b7618bde71dce8cdc73aab6c95905fad240 Ether
0xa9c36f5c8349ab5de3bf6108682d2dcc69899a3d40cfd625de1543da70bb043193093252021-09-17 16:15:3120 hrs 25 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0xa9c36f5c8349ab5de3bf6108682d2dcc69899a3d40cfd625de1543da70bb043193093252021-09-17 16:15:3120 hrs 25 mins ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xf4c5310e51f6079f601a5fb7120bc72a70b96e2a 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0xed5b5b32110c3ded02a07c8b8e97513fafb883b60 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xf4c5310e51f6079f601a5fb7120bc72a70b96e2a 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xa623b2dd931c5162b7a0b25852f4024db48bb1a0 0x6609df3db3f242ceff8b956a4be0326fa6c8f2fb0 Ether
0xf2b8f7c11d0c8b783ac7ef39e08eb59f7949707d8eecb755ef5dc4cc25dc791393073252021-09-17 7:54:511 day 4 hrs ago 0xf4c5310e51f6079f601a5fb7120bc72a70b96e2a 0xa623b2dd931c5162b7a0b25852f4024db48bb1a00 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SETHProxy

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 17 : CustomSuperTokenProxyBase.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import {
    ISuperToken
} from "../../interfaces/superfluid/ISuperToken.sol";
import { UUPSProxy } from "../../upgradability/UUPSProxy.sol";


/**
 * @dev Custom super token proxy base contract
 *
 * NOTE:
 * - Because of how solidity is layouting its storages variables and custom
 *   super token inherits the Super Token standard implementation, so it is
 *   required that the custom token proxy would need to pad its implementation
 *   with reserved storages used by the Super Token implementation.
 * - Refer to SETH.sol for an example how it is used.
 */
abstract contract CustomSuperTokenProxyBase is UUPSProxy {
    // This is the hard-coded number of storage slots used by the super token
    uint256[32] internal _storagePaddings;
}

File 2 of 17 : Definitions.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

/**
 * @dev Super app definitions library
 */
library SuperAppDefinitions {

    /**************************************************************************
    / App manifest config word
    /**************************************************************************/

    /*
     * App level is a way to allow the app to whitelist what other app it can
     * interact with (aka. composite app feature).
     *
     * For more details, refer to the technical paper of superfluid protocol.
     */
    uint256 constant internal APP_LEVEL_MASK = 0xFF;

    // The app is at the final level, hence it doesn't want to interact with any other app
    uint256 constant internal APP_LEVEL_FINAL = 1 << 0;

    // The app is at the second level, it may interact with other final level apps if whitelisted
    uint256 constant internal APP_LEVEL_SECOND = 1 << 1;

    function getAppLevel(uint256 configWord) internal pure returns (uint8) {
        return uint8(configWord & APP_LEVEL_MASK);
    }

    uint256 constant internal APP_JAIL_BIT = 1 << 15;
    function isAppJailed(uint256 configWord) internal pure returns (bool) {
        return (configWord & SuperAppDefinitions.APP_JAIL_BIT) > 0;
    }

    /**************************************************************************
    / Callback implementation bit masks
    /**************************************************************************/
    uint256 constant internal AGREEMENT_CALLBACK_NOOP_BITMASKS = 0xFF << 32;
    uint256 constant internal BEFORE_AGREEMENT_CREATED_NOOP = 1 << (32 + 0);
    uint256 constant internal AFTER_AGREEMENT_CREATED_NOOP = 1 << (32 + 1);
    uint256 constant internal BEFORE_AGREEMENT_UPDATED_NOOP = 1 << (32 + 2);
    uint256 constant internal AFTER_AGREEMENT_UPDATED_NOOP = 1 << (32 + 3);
    uint256 constant internal BEFORE_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 4);
    uint256 constant internal AFTER_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 5);

    /**************************************************************************
    / App Jail Reasons
    /**************************************************************************/

    uint256 constant internal APP_RULE_REGISTRATION_ONLY_IN_CONSTRUCTOR = 1;
    uint256 constant internal APP_RULE_NO_REGISTRATION_FOR_EOA = 2;
    uint256 constant internal APP_RULE_NO_REVERT_ON_TERMINATION_CALLBACK = 10;
    uint256 constant internal APP_RULE_NO_CRITICAL_SENDER_ACCOUNT = 11;
    uint256 constant internal APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT = 12;
    uint256 constant internal APP_RULE_CTX_IS_READONLY = 20;
    uint256 constant internal APP_RULE_CTX_IS_NOT_CLEAN = 21;
    uint256 constant internal APP_RULE_CTX_IS_MALFORMATED = 22;
    uint256 constant internal APP_RULE_COMPOSITE_APP_IS_NOT_WHITELISTED = 30;
    uint256 constant internal APP_RULE_COMPOSITE_APP_IS_JAILED = 31;
    uint256 constant internal APP_RULE_MAX_APP_LEVEL_REACHED = 40;
}

/**
 * @dev Context definitions library
 */
library ContextDefinitions {

    /**************************************************************************
    / Call info
    /**************************************************************************/

    // app level
    uint256 constant internal CALL_INFO_APP_LEVEL_MASK = 0xFF;

    // call type
    uint256 constant internal CALL_INFO_CALL_TYPE_SHIFT = 32;
    uint256 constant internal CALL_INFO_CALL_TYPE_MASK = 0xF << CALL_INFO_CALL_TYPE_SHIFT;
    uint8 constant internal CALL_INFO_CALL_TYPE_AGREEMENT = 1;
    uint8 constant internal CALL_INFO_CALL_TYPE_APP_ACTION = 2;
    uint8 constant internal CALL_INFO_CALL_TYPE_APP_CALLBACK = 3;

    function decodeCallInfo(uint256 callInfo)
        internal pure
        returns (uint8 appLevel, uint8 callType)
    {
        appLevel = uint8(callInfo & CALL_INFO_APP_LEVEL_MASK);
        callType = uint8((callInfo & CALL_INFO_CALL_TYPE_MASK) >> CALL_INFO_CALL_TYPE_SHIFT);
    }

    function encodeCallInfo(uint8 appLevel, uint8 callType)
        internal pure
        returns (uint256 callInfo)
    {
        return uint256(appLevel) | (uint256(callType) << CALL_INFO_CALL_TYPE_SHIFT);
    }

}

/**
 * @dev Batch operation library
 */
library BatchOperation {
    /**
     * @dev ERC20.approve batch operation type
     *
     * Call spec:
     * ISuperToken(target).operationApprove(
     *     abi.decode(data, (address spender, uint256 amount))
     * )
     */
    uint32 constant internal OPERATION_TYPE_ERC20_APPROVE = 1;
    /**
     * @dev ERC20.transferFrom batch operation type
     *
     * Call spec:
     * ISuperToken(target).operationTransferFrom(
     *     abi.decode(data, (address sender, address recipient, uint256 amount)
     * )
     */
    uint32 constant internal OPERATION_TYPE_ERC20_TRANSFER_FROM = 2;
    /**
     * @dev SuperToken.upgrade batch operation type
     *
     * Call spec:
     * ISuperToken(target).operationUpgrade(
     *     abi.decode(data, (uint256 amount)
     * )
     */
    uint32 constant internal OPERATION_TYPE_SUPERTOKEN_UPGRADE = 1 + 100;
    /**
     * @dev SuperToken.downgrade batch operation type
     *
     * Call spec:
     * ISuperToken(target).operationDowngrade(
     *     abi.decode(data, (uint256 amount)
     * )
     */
    uint32 constant internal OPERATION_TYPE_SUPERTOKEN_DOWNGRADE = 2 + 100;
    /**
     * @dev ERC20 Approve batch operation type
     *
     * Call spec:
     * callAgreement(
     *     ISuperAgreement(target)),
     *     abi.decode(data, (bytes calldata, bytes userdata)
     * )
     */
    uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT = 1 + 200;
    /**
     * @dev ERC20 Approve batch operation type
     *
     * Call spec:
     * callAppAction(
     *     ISuperApp(target)),
     *     data
     * )
     */
    uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_APP_ACTION = 2 + 200;
}

File 3 of 17 : ISuperAgreement.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperfluidToken } from "./ISuperfluidToken.sol";

/**
 * @title Superfluid's agreement interface.
 *
 * @author Superfluid
 */
interface ISuperAgreement {

    /**
     * @dev Initialize the agreement contract
     */
    function initialize() external;

    /**
     * @dev Get the type of the agreement class.
     */
    function agreementType() external view returns (bytes32);

    /**
     * @dev Calculate the real-time balance for the account of this agreement class.
     * @param account Account the state belongs to
     * @param time Future time used for the calculation.
     * @return dynamicBalance Dynamic balance portion of real-time balance of this agreement.
     * @return deposit Account deposit amount of this agreement.
     * @return owedDeposit Account owed deposit amount of this agreement.
     */
    function realtimeBalanceOf(
        ISuperfluidToken token,
        address account,
        uint256 time
    )
        external
        view
        returns (
            int256 dynamicBalance,
            uint256 deposit,
            uint256 owedDeposit
        );

}

File 4 of 17 : ISuperApp.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperToken } from "./ISuperToken.sol";


/**
 * @title Superfluid's app interface.
 *
 * NOTE:
 * - Be fearful of the app jail, when the word permitted is used.
 *
 * @author Superfluid
 */
interface ISuperApp {

    /**
     * @dev Callback before a new agreement is created.
     * @param superToken The super token used for the agreement.
     * @param agreementClass The agreement class address.
     * @param agreementId The agreementId
     * @param agreementData The agreement data (non-compressed)
     * @param ctx The context data.
     * @return cbdata A free format in memory data the app can use to pass
     *          arbitary information to the after-hook callback.
     *
     * NOTE:
     * - It will be invoked with `staticcall`, no state changes are permitted.
     * - Only revert with a "reason" is permitted.
     */
    function beforeAgreementCreated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata ctx
    )
        external
        view
        returns (bytes memory cbdata);

    /**
     * @dev Callback after a new agreement is created.
     * @param superToken The super token used for the agreement.
     * @param agreementClass The agreement class address.
     * @param agreementId The agreementId
     * @param agreementData The agreement data (non-compressed)
     * @param cbdata The data returned from the before-hook callback.
     * @param ctx The context data.
     * @return newCtx The current context of the transaction.
     *
     * NOTE:
     * - State changes is permitted.
     * - Only revert with a "reason" is permitted.
     */
    function afterAgreementCreated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata cbdata,
        bytes calldata ctx
    )
        external
        returns (bytes memory newCtx);

    /**
     * @dev Callback before a new agreement is updated.
     * @param superToken The super token used for the agreement.
     * @param agreementClass The agreement class address.
     * @param agreementId The agreementId
     * @param agreementData The agreement data (non-compressed)
     * @param ctx The context data.
     * @return cbdata A free format in memory data the app can use to pass
     *          arbitary information to the after-hook callback.
     *
     * NOTE:
     * - It will be invoked with `staticcall`, no state changes are permitted.
     * - Only revert with a "reason" is permitted.
     */
    function beforeAgreementUpdated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata ctx
    )
        external
        view
        returns (bytes memory cbdata);


    /**
    * @dev Callback after a new agreement is updated.
    * @param superToken The super token used for the agreement.
    * @param agreementClass The agreement class address.
    * @param agreementId The agreementId
    * @param agreementData The agreement data (non-compressed)
    * @param cbdata The data returned from the before-hook callback.
    * @param ctx The context data.
    * @return newCtx The current context of the transaction.
    *
    * NOTE:
    * - State changes is permitted.
    * - Only revert with a "reason" is permitted.
    */
    function afterAgreementUpdated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata cbdata,
        bytes calldata ctx
    )
        external
        returns (bytes memory newCtx);

    /**
    * @dev Callback before a new agreement is terminated.
    * @param superToken The super token used for the agreement.
    * @param agreementClass The agreement class address.
    * @param agreementId The agreementId
    * @param agreementData The agreement data (non-compressed)
    * @param ctx The context data.
    * @return cbdata A free format in memory data the app can use to pass
    *          arbitary information to the after-hook callback.
    *
    * NOTE:
    * - It will be invoked with `staticcall`, no state changes are permitted.
    * - Revert is not permitted.
    */
    function beforeAgreementTerminated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata ctx
    )
        external
        view
        returns (bytes memory cbdata);

    /**
    * @dev Callback after a new agreement is terminated.
    * @param superToken The super token used for the agreement.
    * @param agreementClass The agreement class address.
    * @param agreementId The agreementId
    * @param agreementData The agreement data (non-compressed)
    * @param cbdata The data returned from the before-hook callback.
    * @param ctx The context data.
    * @return newCtx The current context of the transaction.
    *
    * NOTE:
    * - State changes is permitted.
    * - Revert is not permitted.
    */
    function afterAgreementTerminated(
        ISuperToken superToken,
        address agreementClass,
        bytes32 agreementId,
        bytes calldata agreementData,
        bytes calldata cbdata,
        bytes calldata ctx
    )
        external
        returns (bytes memory newCtx);
}

File 5 of 17 : ISuperToken.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperfluid } from "./ISuperfluid.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { TokenInfo } from "../tokens/TokenInfo.sol";
import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title Superfluid's super token (Superfluid Token + ERC20 + ERC777) interface
 *
 * @author Superfluid
 */
interface ISuperToken is ISuperfluidToken, TokenInfo, IERC20, IERC777 {

    /// @dev Initialize the contract
    function initialize(
        IERC20 underlyingToken,
        uint8 underlyingDecimals,
        string calldata n,
        string calldata s
    ) external;

    /**************************************************************************
    * TokenInfo & ERC777
    *************************************************************************/

    /**
     * @dev Returns the name of the token.
     */
    function name() external view override(IERC777, TokenInfo) returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view override(IERC777, TokenInfo) returns (string memory);

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: SuperToken always uses 18 decimals.
     *
     * Note: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() external view override(TokenInfo) returns (uint8);

    /**************************************************************************
    * ERC20 & ERC777
    *************************************************************************/

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() external view override(IERC777, IERC20) returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by an account (`owner`).
     */
    function balanceOf(address account) external view override(IERC777, IERC20) returns(uint256 balance);

    /**************************************************************************
    * ERC20
    *************************************************************************/

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external override(IERC20) view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external override(IERC20) returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external override(IERC20) returns (bool);

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) external returns (bool);

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
     function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);

    /**************************************************************************
    * ERC777
    *************************************************************************/

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For super token contracts, this value is 1 always
     */
    function granularity() external view override(IERC777) returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777);

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external override(IERC777);

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external override(IERC777) view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external override(IERC777);

    /**
     * @dev Revoke an account's operator status for the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external override(IERC777);

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external override(IERC777) view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external override(IERC777);

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external override(IERC777);

    /**************************************************************************
     * SuperToken custom token functions
     *************************************************************************/

    /**
     * @dev Mint new tokens for the account
     *
     * Modifiers:
     *  - onlySelf
     */
    function selfMint(
        address account,
        uint256 amount,
        bytes memory userData
    ) external;

   /**
    * @dev Burn existing tokens for the account
    *
    * Modifiers:
    *  - onlySelf
    */
   function selfBurn(
       address account,
       uint256 amount,
       bytes memory userData
   ) external;

    /**************************************************************************
     * SuperToken extra functions
     *************************************************************************/

    /**
     * @dev Transfer all available balance from `msg.sender` to `recipient`
     */
    function transferAll(address recipient) external;

    /**************************************************************************
     * ERC20 wrapping
     *************************************************************************/

    /**
     * @dev Return the underlaying token contract
     * @return tokenAddr Underlying token address
     */
    function getUnderlyingToken() external view returns(address tokenAddr);

    /**
     * @dev Upgrade ERC20 to SuperToken.
     * @param amount Number of tokens to be upgraded (in 18 decimals)
     *
     * NOTE: It will use ´transferFrom´ to get tokens. Before calling this
     * function you should ´approve´ this contract
     */
    function upgrade(uint256 amount) external;

    /**
     * @dev Upgrade ERC20 to SuperToken and transfer immediately
     * @param to The account to received upgraded tokens
     * @param amount Number of tokens to be upgraded (in 18 decimals)
     * @param data User data for the TokensRecipient callback
     *
     * NOTE: It will use ´transferFrom´ to get tokens. Before calling this
     * function you should ´approve´ this contract
     */
    function upgradeTo(address to, uint256 amount, bytes calldata data) external;

    /**
     * @dev Token upgrade event
     * @param account Account whose tokens are upgraded
     * @param amount Amount of tokens upgraded (in 18 decimals)
     */
    event TokenUpgraded(
        address indexed account,
        uint256 amount
    );

    /**
     * @dev Downgrade SuperToken to ERC20.
     * @dev It will call transfer to send tokens
     * @param amount Number of tokens to be downgraded
     */
    function downgrade(uint256 amount) external;

    /**
     * @dev Token downgrade event
     * @param account Account whose tokens are upgraded
     * @param amount Amount of tokens downgraded
     */
    event TokenDowngraded(
        address indexed account,
        uint256 amount
    );

    /**************************************************************************
    * Batch Operations
    *************************************************************************/

    /**
    * @dev Perform ERC20 approve by host contract.
    * @param account The account owner to be approved.
    * @param spender The spender of account owner's funds.
    * @param amount Number of tokens to be approved.
    *
    * Modifiers:
    *  - onlyHost
    */
    function operationApprove(
        address account,
        address spender,
        uint256 amount
    ) external;

    /**
    * @dev Perform ERC20 transfer from by host contract.
    * @param account The account to spend sender's funds.
    * @param spender  The account where the funds is sent from.
    * @param recipient The recipient of thefunds.
    * @param amount Number of tokens to be transferred.
    *
    * Modifiers:
    *  - onlyHost
    */
    function operationTransferFrom(
        address account,
        address spender,
        address recipient,
        uint256 amount
    ) external;

    /**
    * @dev Upgrade ERC20 to SuperToken by host contract.
    * @param account The account to be changed.
    * @param amount Number of tokens to be upgraded (in 18 decimals)
    *
    * Modifiers:
    *  - onlyHost
    */
    function operationUpgrade(address account, uint256 amount) external;

    /**
    * @dev Downgrade ERC20 to SuperToken by host contract.
    * @param account The account to be changed.
    * @param amount Number of tokens to be downgraded (in 18 decimals)
    *
    * Modifiers:
    *  - onlyHost
    */
    function operationDowngrade(address account, uint256 amount) external;


    /**************************************************************************
    * Function modifiers for access control and parameter validations
    *
    * While they cannot be explicitly stated in function definitions, they are
    * listed in function definition comments instead for clarity.
    *
    * NOTE: solidity-coverage not supporting it
    *************************************************************************/

    /// @dev The msg.sender must be the contract itself
    //modifier onlySelf() virtual

}

File 6 of 17 : ISuperTokenFactory.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperToken } from "./ISuperToken.sol";

import {
    IERC20,
    ERC20WithTokenInfo
} from "../tokens/ERC20WithTokenInfo.sol";


interface ISuperTokenFactory {

    /**
     * @dev Get superfluid host contract address
     */
    function getHost() external view returns(address host);

    /// @dev Initialize the contract
    function initialize() external;

    /**
     * @dev Get the current super token logic used by the factory
     */
    function getSuperTokenLogic() external view returns (ISuperToken superToken);

    /**
     * @dev Upgradability modes
     */
    enum Upgradability {
        /// Non upgradable super token, `host.updateSuperTokenLogic` will revert
        NON_UPGRADABLE,
        /// Upgradable through `host.updateSuperTokenLogic` operation
        SEMI_UPGRADABLE,
        /// Always using the latest super token logic
        FULL_UPGRADABE
    }

    /**
     * @dev Create new super token wrapper for the underlying ERC20 token
     * @param underlyingToken Underlying ERC20 token
     * @param underlyingDecimals Underlying token decimals
     * @param upgradability Upgradability mode
     * @param name Super token name
     * @param symbol Super token symbol
     */
    function createERC20Wrapper(
        IERC20 underlyingToken,
        uint8 underlyingDecimals,
        Upgradability upgradability,
        string calldata name,
        string calldata symbol
    )
        external;

    /**
     * @dev Create new super token wrapper for the underlying ERC20 token with extra token info
     * @param underlyingToken Underlying ERC20 token
     * @param upgradability Upgradability mode
     * @param name Super token name
     * @param symbol Super token symbol
     *
     * NOTE:
     * - It assumes token provide the .decimals() function
     */
    function createERC20Wrapper(
        ERC20WithTokenInfo underlyingToken,
        Upgradability upgradability,
        string calldata name,
        string calldata symbol
    )
        external;

    function initializeCustomSuperToken(
        address customSuperTokenProxy
    )
        external;

    event SuperTokenLogicCreated(ISuperToken indexed tokenLogic);

    event SuperTokenCreated(ISuperToken indexed token);

}

File 7 of 17 : ISuperfluid.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;
// This is required by the batchCall and decodeCtx
pragma experimental ABIEncoderV2;

import { ISuperfluidGovernance } from "./ISuperfluidGovernance.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { ISuperToken } from "./ISuperToken.sol";
import { ISuperTokenFactory } from "./ISuperTokenFactory.sol";
import { ISuperAgreement } from "./ISuperAgreement.sol";
import { ISuperApp } from "./ISuperApp.sol";
import {
    SuperAppDefinitions,
    ContextDefinitions,
    BatchOperation
} from "./Definitions.sol";
import { TokenInfo } from "../tokens/TokenInfo.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";


/**
 * @dev Superfluid host interface.

 * It is the central contract of the system where super agreement, super app
 * and super token features are connected together.
 *
 * The superfluid host contract is also the entry point for the protocol users,
 * where batch call and meta transaction are provided for UX improvements.
 *
 * @author Superfluid
 */
interface ISuperfluid {

    /**************************************************************************
     * Governance
     *************************************************************************/

    /**
     * @dev Get the current governace of the Superfluid host
     */
    function getGovernance() external view returns(ISuperfluidGovernance governance);

    /**
     * @dev Replace the current governance with a new one
     */
    function replaceGovernance(ISuperfluidGovernance newGov) external;

    /**************************************************************************
     * Agreement Whitelisting
     *************************************************************************/

    /**
     * @dev Register a new agreement class to the system
     * @param agreementClassLogic INitial agreement class code
     *
     * Modifiers:
     *  - onlyGovernance
     */
    function registerAgreementClass(ISuperAgreement agreementClassLogic) external;

    /**
    * @dev Update code of an agreement class
    * @param agreementClassLogic New code for the agreement class
    *
    * Modifiers:
    *  - onlyGovernance
    */
    function updateAgreementClass(ISuperAgreement agreementClassLogic) external;

    /**
    * @dev Check if the agreement class is whitelisted
    */
    function isAgreementTypeListed(bytes32 agreementType) external view returns(bool yes);

    /**
    * @dev Check if the agreement class is whitelisted
    */
    function isAgreementClassListed(ISuperAgreement agreementClass) external view returns(bool yes);

    /**
    * @dev Get agreement class
    */
    function getAgreementClass(bytes32 agreementType) external view returns(ISuperAgreement agreementClass);

    /**
    * @dev Map list of the agreement classes using a bitmap
    * @param bitmap Agreement class bitmap
    */
    function mapAgreementClasses(uint256 bitmap)
        external view
        returns (ISuperAgreement[] memory agreementClasses);

    /**
    * @dev Create a new bitmask by adding a agreement class to it.
    * @param bitmap Agreement class bitmap
    */
    function addToAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType)
        external view
        returns (uint256 newBitmap);

    /**
    * @dev Create a new bitmask by removing a agreement class from it.
    * @param bitmap Agreement class bitmap
    */
    function removeFromAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType)
        external view
        returns (uint256 newBitmap);

    /**************************************************************************
    * Super Token Factory
    **************************************************************************/

    /**
     * @dev Get the super token factory
     * @return factory The factory
     */
    function getSuperTokenFactory() external view returns (ISuperTokenFactory factory);

    /**
     * @dev Get the super token factory logic (applicable to upgradable deployment)
     * @return logic The factory logic
     */
    function getSuperTokenFactoryLogic() external view returns (address logic);

    /**
     * @dev Update super token factory
     * @param newFactory New factory logic
     */
    function updateSuperTokenFactory(ISuperTokenFactory newFactory) external;

    /**
     * @dev Update the super token logic to the latest
     *
     * NOTE:
     * - Refer toISuperTokenFactory.Upgradability for expected behaviours.
     */
    function updateSuperTokenLogic(ISuperToken token) external;

    /**************************************************************************
     * App Registry
     *************************************************************************/

    /**
     * @dev Message sender declares it as a super app
     * @param configWord The super app manifest configuration, flags are defined in
     *                   `SuperAppDefinitions`
     */
    function registerApp(uint256 configWord) external;

    /**
     * @dev Query if the app is registered
     * @param app Super app address
     */
    function isApp(ISuperApp app) external view returns(bool);

    /**
     * @dev Query app level
     * @param app Super app address
     */
    function getAppLevel(ISuperApp app) external view returns(uint8 appLevel);

    /**
     * @dev Get the manifest of the super app
     * @param app Super app address
     */
    function getAppManifest(
        ISuperApp app
    )
        external view
        returns (
            bool isSuperApp,
            bool isJailed,
            uint256 noopMask
        );

    /**
     * @dev Query if the app has been jailed
     * @param app Super app address
     */
    function isAppJailed(ISuperApp app) external view returns (bool isJail);

    /**
     * @dev White-list the target app for app composition for the source app (msg.sender)
     * @param targetApp The taget super app address
     */
    function allowCompositeApp(ISuperApp targetApp) external;

    /**
     * @dev Query if source app  is allowed to call the target app as downstream app.
     * @param app Super app address
     * @param targetApp The taget super app address
     */
    function isCompositeAppAllowed(
        ISuperApp app,
        ISuperApp targetApp
    )
        external view
        returns (bool isAppAllowed);

    /**
     * @dev Jail event for the app
     */
    event Jail(ISuperApp indexed app, uint256 reason);

    /**************************************************************************
     * Agreement Framework
     *
     * Agreements use these function to trigger super app callbacks, updates
     * app allowance and charge gas fees.
     *
     * These functions can only be called by registered agreements.
     *************************************************************************/

    function callAppBeforeCallback(
        ISuperApp app,
        bytes calldata callData,
        bool isTermination,
        bytes calldata ctx
    )
        external
        // onlyAgreement
        // isAppActive(app)
        returns(bytes memory cbdata);

    function callAppAfterCallback(
        ISuperApp app,
        bytes calldata callData,
        bool isTermination,
        bytes calldata ctx
    )
        external
        // onlyAgreement
        // isAppActive(app)
        returns(bytes memory appCtx);

    function appCallbackPush(
        bytes calldata ctx,
        ISuperApp app,
        uint256 appAllowanceGranted,
        int256 appAllowanceUsed
    )
        external
        // onlyAgreement
        returns (bytes memory appCtx);

    function appCallbackPop(
        bytes calldata ctx,
        int256 allowanceUsedDelta
    )
        external
        // onlyAgreement
        returns (bytes memory newCtx);

    function ctxUseAllowance(
        bytes calldata ctx,
        uint256 allowanceWantedMore,
        int256 allowanceUsedDelta
    )
        external
        // onlyAgreement
        returns (bytes memory newCtx);

    function jailApp(
        bytes calldata ctx,
        ISuperApp app,
        uint256 reason
    )
        external
        // onlyAgreement
        returns (bytes memory newCtx);

    /**************************************************************************
     * Contextless Call Proxies
     *
     * NOTE: For EOAs or non-app contracts, they are the entry points for interacting
     * with agreements or apps.
     *
     * NOTE: The contextual call data should be generated using
     * abi.encodeWithSelector. The context parameter should be set to "0x",
     * an empty bytes array as a placeholder to be replaced by the host
     * contract.
     *************************************************************************/

     /**
      * @dev Call agreement function
      * @param callData The contextual call data with placeholder ctx
      * @param userData Extra user data being sent to the super app callbacks
      */
     function callAgreement(
         ISuperAgreement agreementClass,
         bytes calldata callData,
         bytes calldata userData
     )
        external
        //cleanCtx
        returns(bytes memory returnedData);

    /**
     * @dev Call app action
     * @param callData The contextual call data.
     *
     * NOTE: See callAgreement about contextual call data.
     */
    function callAppAction(
        ISuperApp app,
        bytes calldata callData
    )
        external
        //cleanCtx
        //isAppActive(app)
        returns(bytes memory returnedData);

    /**************************************************************************
     * Contextual Call Proxies and Context Utilities
     *
     * For apps, they must use context they receive to interact with
     * agreements or apps.
     *
     * The context changes must be saved and returned by the apps in their
     * callbacks always, any modification to the context will be detected and
     * the violating app will be jailed.
     *************************************************************************/

    /**
     * @dev ABIv2 Encoded memory data of context
     *
     * NOTE on backward compatibility:
     * - Non-dynamic fields are padded to 32bytes and packed
     * - Dynamic fields are referenced through a 32bytes offset to their "parents" field (or root)
     * - The order of the fields hence should not be rearranged in order to be backward compatible:
     *    - non-dynamic fields will be parsed at the same memory location,
     *    - and dynamic fields will simply have a greater offset than it was.
     */
    struct Context {
        //
        // Call context
        //
        // callback level
        uint8 appLevel;
        // type of call
        uint8 callType;
        // the system timestsamp
        uint256 timestamp;
        // The intended message sender for the call
        address msgSender;

        //
        // Callback context
        //
        // For callbacks it is used to know which agreement function selector is called
        bytes4 agreementSelector;
        // User provided data for app callbacks
        bytes userData;

        //
        // App context
        //
        // app allowance granted
        uint256 appAllowanceGranted;
        // app allowance wanted by the app callback
        uint256 appAllowanceWanted;
        // app allowance used, allowing negative values over a callback session
        int256 appAllowanceUsed;
    }

    function callAgreementWithContext(
        ISuperAgreement agreementClass,
        bytes calldata callData,
        bytes calldata userData,
        bytes calldata ctx
    )
        external
        // validCtx(ctx)
        // onlyAgreement(agreementClass)
        returns (bytes memory newCtx, bytes memory returnedData);

    function callAppActionWithContext(
        ISuperApp app,
        bytes calldata callData,
        bytes calldata ctx
    )
        external
        // validCtx(ctx)
        // isAppActive(app)
        returns (bytes memory newCtx);

    function decodeCtx(bytes calldata ctx)
        external pure
        returns (Context memory context);

    function isCtxValid(bytes calldata ctx) external view returns (bool);

    /**************************************************************************
    * Batch call
    **************************************************************************/
    /**
     * @dev Batch operation data
     */
    struct Operation {
        // Operation. Defined in BatchOperation (Definitions.sol)
        uint32 operationType;
        // Operation target
        address target;
        // Data specific to the operation
        bytes data;
    }

    /**
     * @dev Batch call function.
     * @param operations Array of batch operations.
     */
    function batchCall(Operation[] memory operations) external;

    /**************************************************************************
     * Function modifiers for access control and parameter validations
     *
     * While they cannot be explicitly stated in function definitions, they are
     * listed in function definition comments instead for clarity.
     *
     * TODO: turning these off because solidity-coverage don't like it
     *************************************************************************/

     /* /// @dev The current superfluid context is clean.
     modifier cleanCtx() virtual;

     /// @dev The superfluid context is valid.
     modifier validCtx(bytes memory ctx) virtual;

     /// @dev The agreement is a listed agreement.
     modifier isAgreement(ISuperAgreement agreementClass) virtual;

     // onlyGovernance

     /// @dev The msg.sender must be a listed agreement.
     modifier onlyAgreement() virtual;

     /// @dev The app is registered and not jailed.
     modifier isAppActive(ISuperApp app) virtual; */
}

File 8 of 17 : ISuperfluidGovernance.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperAgreement } from "./ISuperAgreement.sol";
import { ISuperToken } from "./ISuperToken.sol";
import { ISuperfluidToken  } from "./ISuperfluidToken.sol";
import { ISuperfluid } from "./ISuperfluid.sol";


/**
 * @dev Superfluid's Governance interface
 *
 * @author Superfluid
 */
interface ISuperfluidGovernance {

    /**
     * @dev Replace the current governance with a new governance
     */
    function replaceGovernance(
        ISuperfluid host,
        address newGov) external;

    /**
     * @dev Register a new agreement class
     */
    function registerAgreementClass(
        ISuperfluid host,
        address agreementClass) external;

    /**
     * @dev Update logics of the contracts
     *
     * NOTE:
     * - Because they might have inter-dependencies, it is good to have one single function to update them all
     */
    function updateContracts(
        ISuperfluid host,
        address hostNewLogic,
        address[] calldata agreementClassNewLogics,
        address superTokenFactoryNewLogic
    ) external;

    /**
     * @dev Update supertoken logic contract to the latest that is managed by the super token factory
     */
    function updateSuperTokenLogic(
        ISuperfluid host,
        ISuperToken token) external;

    /// @dev Get configuration as address value
    function getConfigAsAddress(
        ISuperfluid host,
        ISuperfluidToken superToken,
        bytes32 key) external view returns (address value);

    /// @dev Get configuration as uint256 value
    function getConfigAsUint256(
        ISuperfluid host,
        ISuperfluidToken superToken,
        bytes32 key) external view returns (uint256 value);

}

File 9 of 17 : ISuperfluidToken.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.7.0;

import { ISuperAgreement } from "./ISuperAgreement.sol";


/**
 * @title Superfluid's token interface.
 *
 * @author Superfluid
 */
interface ISuperfluidToken {

    /**************************************************************************
     * Basic information
     *************************************************************************/

    /**
     * @dev Get superfluid host contract address
     */
    function getHost() external view returns(address host);

    /**************************************************************************
     * Real-time balance functions
     *************************************************************************/

    /**
    * @dev Calculate the real balance of a user, taking in consideration all agreements of the account
    * @param account for the query
    * @param timestamp Time of balance
    * @param account Account to query
    * @return availableBalance Real-time balance
    * @return deposit Account deposit
    * @return owedDeposit Account owed Deposit
    */
    function realtimeBalanceOf(
       address account,
       uint256 timestamp
    )
        external view
        returns (
            int256 availableBalance,
            uint256 deposit,
            uint256 owedDeposit);

    /// @dev realtimeBalanceOf with timestamp equals to block timestamp
    function realtimeBalanceOfNow(
       address account
    )
        external view
        returns (
            int256 availableBalance,
            uint256 deposit,
            uint256 owedDeposit,
            uint256 timestamp);

    /**
    * @dev Check if one account is critical
    * @param account Account check if is critical by a future time
    * @param timestamp Time of balance
    * @return isCritical
    */
    function isAccountCritical(
        address account,
        uint256 timestamp
    )
        external view
        returns(bool isCritical);

    /**
    * @dev Check if one account is critical now
    * @param account Account check if is critical by a future time
    * @return isCritical
    */
    function isAccountCriticalNow(
        address account
    )
        external view
        returns(bool isCritical);

    /**
     * @dev Check if one account is solvent
     * @param account Account check if is solvent by a future time
     * @param timestamp Time of balance
     * @return isSolvent
     */
    function isAccountSolvent(
        address account,
        uint256 timestamp
    )
        external view
        returns(bool isSolvent);

    /**
     * @dev Check if one account is solvent now
     * @param account Account check if is solvent now
     * @return isSolvent
     */
    function isAccountSolventNow(
        address account
    )
        external view
        returns(bool isSolvent);

    /**
    * @dev Get a list of agreements that is active for the account
    * @dev An active agreement is one that has state for the account
    * @param account Account to query
    * @return activeAgreements List of accounts that have non-zero states for the account
    */
    function getAccountActiveAgreements(address account)
       external view
       returns(ISuperAgreement[] memory activeAgreements);


   /**************************************************************************
    * Super Agreement hosting functions
    *************************************************************************/

    /**
     * @dev Create a new agreement
     * @param id Agreement ID
     * @param data Agreement data
     */
    function createAgreement(
        bytes32 id,
        bytes32[] calldata data
    )
        external;

    /**
     * @dev Agreement creation event
     * @param agreementClass Contract address of the agreement
     * @param id Agreement ID
     * @param data Agreement data
     */
    event AgreementCreated(
        address indexed agreementClass,
        bytes32 id,
        bytes32[] data
    );

    /**
     * @dev Get data of the agreement
     * @param agreementClass Contract address of the agreement
     * @param id Agreement ID
     * @return data Data of the agreement
     */
    function getAgreementData(
        address agreementClass,
        bytes32 id,
        uint dataLength
    )
        external view
        returns(bytes32[] memory data);

    /**
     * @dev Create a new agreement
     * @param id Agreement ID
     * @param data Agreement data
     */
    function updateAgreementData(
        bytes32 id,
        bytes32[] calldata data
    )
        external;

    /**
     * @dev Agreement creation event
     * @param agreementClass Contract address of the agreement
     * @param id Agreement ID
     * @param data Agreement data
     */
    event AgreementUpdated(
        address indexed agreementClass,
        bytes32 id,
        bytes32[] data
    );

    /**
     * @dev Close the agreement
     * @param id Agreement ID
     */
    function terminateAgreement(
        bytes32 id,
        uint dataLength
    )
        external;

    /**
     * @dev Agreement termination event
     * @param agreementClass Contract address of the agreement
     * @param id Agreement ID
     */
    event AgreementTerminated(
        address indexed agreementClass,
        bytes32 id
    );

    /**
     * @dev Update agreement state slot
     * @param account Account to be updated
     *
     * NOTE
     * - To clear the storage out, provide zero-ed array of intended length
     */
    function updateAgreementStateSlot(
        address account,
        uint256 slotId,
        bytes32[] calldata slotData
    )
        external;

    /**
     * @dev Agreement account state updated event
     * @param agreementClass Contract address of the agreement
     * @param account Account updated
     * @param slotId slot id of the agreement state
     */
    event AgreementStateUpdated(
        address indexed agreementClass,
        address indexed account,
        uint256 slotId
    );

    /**
     * @dev Get data of the slot of the state of a agreement
     * @param agreementClass Contract address of the agreement
     * @param account Account to query
     * @param slotId slot id of the state
     * @param dataLength length of the state data
     */
    function getAgreementStateSlot(
        address agreementClass,
        address account,
        uint256 slotId,
        uint dataLength
    )
        external view
        returns (bytes32[] memory slotData);

    /**
     * @dev Agreement account state updated event
     * @param agreementClass Contract address of the agreement
     * @param account Account of the agrement
     * @param state Agreement state of the account
     */
    event AgreementAccountStateUpdated(
        address indexed agreementClass,
        address indexed account,
        bytes state
    );

    /**
     * @dev Settle balance from an account by the agreement.
     *      The agreement needs to make sure that the balance delta is balanced afterwards
     * @param account Account to query.
     * @param delta Amount of balance delta to be settled
     *
     * Modifiers:
     *  - onlyAgreement
     */
    function settleBalance(
        address account,
        int256 delta
    )
        external;

    /**
     * @dev Agreement liquidation event
     * @param agreementClass Contract address of the agreement
     * @param id Agreement ID
     * @param penaltyAccount Account of the agreement to be penalized
     * @param rewardAccount Account that collect the reward
     * @param rewardAmount Amount of liquidation reward
     */
    event AgreementLiquidated(
        address indexed agreementClass,
        bytes32 id,
        address indexed penaltyAccount,
        address indexed rewardAccount,
        uint256 rewardAmount
    );

    /**
     * @dev System bailout occurred
     * @param bailoutAccount Account that bailout the penalty account
     * @param bailoutAmount Amount of account bailout
     */
    event Bailout(
        address indexed bailoutAccount,
        uint256 bailoutAmount
    );

    /**
     * @dev Make liquidation payouts
     * @param id Agreement ID
     * @param liquidator Address of the executer of liquidation
     * @param penaltyAccount Account of the agreement to be penalized
     * @param rewardAmount Amount of liquidation reward
     * @param bailoutAmount Amount of account bailout needed
     *
     * NOTE:
     * Liquidation rules:
     *  - If a bailout is required (bailoutAmount > 0)
     *     - the actual reward goes to the liquidator,
     *     - while the reward account becomes the bailout account
     *     - total bailout include: bailout amount + reward amount
     *
     * Modifiers:
     *  - onlyAgreement
     */
    function makeLiquidationPayouts
    (
        bytes32 id,
        address liquidator,
        address penaltyAccount,
        uint256 rewardAmount,
        uint256 bailoutAmount
    )
        external;

    /**************************************************************************
     * Function modifiers for access control and parameter validations
     *
     * While they cannot be explicitly stated in function definitions, they are
     * listed in function definition comments instead for clarity.
     *
     * NOTE: solidity-coverage not supporting it
     *************************************************************************/

     /// @dev The msg.sender must be host contract
     //modifier onlyHost() virtual;

    /// @dev The msg.sender must be a listed agreement.
    //modifier onlyAgreement() virtual;

}

File 10 of 17 : ERC20WithTokenInfo.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.5.0;

import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { TokenInfo } from "./TokenInfo.sol";


/**
 *
 * @dev Interface for ERC20 token with token info
 *
 * NOTE: Using abstract contract instead of interfaces because old solidity
 * does not support interface inheriting other interfaces
 * solhint-disable-next-line no-empty-blocks
 *
 */
// solhint-disable-next-line no-empty-blocks
abstract contract ERC20WithTokenInfo is IERC20, TokenInfo {}

File 11 of 17 : TokenInfo.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.5.0;

/**
 * @dev ERC20 token info interface
 *
 * NOTE: ERC20 standard interface does not specify these functions, but
 * often the token implementations have them.
 *
 */
interface TokenInfo {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() external view returns (uint8);
}

File 12 of 17 : SETH.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity 0.7.6;

import {
    ISuperToken,
    CustomSuperTokenProxyBase
}
from "../interfaces/superfluid/CustomSuperTokenProxyBase.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { UUPSProxy } from "../upgradability/UUPSProxy.sol";


/**
 * @dev Wrapped ETH interface
 */
interface IWETH is IERC20 {
    function deposit() external payable;
    function withdraw(uint wad) external;
}


/**
 * @dev Super ETH (SETH) custom token functions
 *
 * @author Superfluid
 */
interface ISETHCustom {
    function upgradeByETH() external payable;
    function upgradeByETHTo(address to) external payable;
    function upgradeByWETH(uint wad) external;
    function downgradeToETH(uint wad) external;
    function downgradeToWETH(uint wad) external;
}

/**
 * @dev Super ETH (SETH) full interface
 *
 * @author Superfluid
 */
// solhint-disable-next-line no-empty-blocks
interface ISETH is ISETHCustom, ISuperToken { }

/**
 * SETH receive fallback logic contract
 */
contract SETHReceiveLogic {

    IWETH immutable private _weth;

    constructor(IWETH weth) {
        _weth = weth;
    }

    receive() external payable {
        if (msg.sender != address(_weth)) {
            // if non weth contract sends us eth, we upgrade some SETH to them
            ISuperToken(address(this)).selfMint(msg.sender, msg.value, new bytes(0));
        } // else it is weth, it is already implemented in upgrade (ByWETH)
    }
}

/**
 * @dev Super ETH (SETH) custom super totken implementation
 *
 * @author Superfluid
 */
contract SETHProxy is ISETHCustom, CustomSuperTokenProxyBase {

    IWETH immutable private _weth;
    SETHReceiveLogic private _receiveLogic;

    constructor(IWETH weth) {
        _weth = weth;
        _receiveLogic = new SETHReceiveLogic(weth);
    }

    function _implementation() internal override view returns (address)
    {
        if (msg.data.length > 0) {
            return UUPSProxy._implementation();
        } else {
            // do not provide receive() fallback otherwise it can't
            // withdraw WETH
            return address(_receiveLogic);
        }
    }

    function upgradeByETH() external override payable {
        ISuperToken(address(this)).selfMint(msg.sender, msg.value, new bytes(0));
        emit TokenUpgraded(msg.sender, msg.value);
    }

    function upgradeByETHTo(address to) external override payable {
        ISuperToken(address(this)).selfMint(to, msg.value, new bytes(0));
        emit TokenUpgraded(to, msg.value);
    }

    function upgradeByWETH(uint wad) external override {
        _weth.transferFrom(msg.sender, address(this), wad);
        // this will trigger receive() which is overriden to a no-op
        _weth.withdraw(wad);
        ISuperToken(address(this)).selfMint(msg.sender, wad, new bytes(0));
        emit TokenUpgraded(msg.sender, wad);
    }

    function downgradeToETH(uint wad) external override {
        ISuperToken(address(this)).selfBurn(msg.sender, wad, new bytes(0));
        msg.sender.transfer(wad);
        emit TokenDowngraded(msg.sender, wad);
    }

    function downgradeToWETH(uint wad) external override {
        ISuperToken(address(this)).selfBurn(msg.sender, wad, new bytes(0));
        _weth.deposit{ value: wad }();
        _weth.transfer(msg.sender, wad);
        emit TokenDowngraded(msg.sender, wad);
    }

    event TokenUpgraded(
        address indexed account,
        uint256 amount
    );

    event TokenDowngraded(
        address indexed account,
        uint256 amount
    );

}

File 13 of 17 : UUPSProxy.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity 0.7.6;

import { UUPSUtils } from "./UUPSUtils.sol";
import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol";


/**
 * @dev UUPS (Universal Upgradeable Proxy Standard) Proxy
 *
 * NOTE:
 * - Compliant with [Universal Upgradeable Proxy Standard](https://eips.ethereum.org/EIPS/eip-1822)
 * - Compiiant with [Standard Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967)
 * - Implements delegation of calls to other contracts, with proper forwarding of
 *   return values and bubbling of failures.
 * - It defines a fallback function that delegates all calls to the implementation.
 */
contract UUPSProxy is Proxy {

    /**
     * @dev Proxy initialization function.
     *      This should only be called once and it is permission-less.
     * @param initialAddress Initial logic contract code address to be used.
     */
    function initializeProxy(address initialAddress) external {
        require(initialAddress != address(0), "UUPSProxy: zero address");
        require(UUPSUtils.implementation() == address(0), "UUPSProxy: already initialized");
        UUPSUtils.setImplementation(initialAddress);
    }

    /// @dev Proxy._implementation implementation
    function _implementation() internal virtual override view returns (address)
    {
        return UUPSUtils.implementation();
    }

}

File 14 of 17 : UUPSUtils.sol
// SPDX-License-Identifier: AGPLv3
pragma solidity 0.7.6;

/**
 * @title UUPS (Universal Upgradeable Proxy Standard) Shared Library
 */
library UUPSUtils {

    /**
     * @dev Implementation slot constant.
     * Using https://eips.ethereum.org/EIPS/eip-1967 standard
     * Storage slot 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc
     * (obtained as bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)).
     */
    bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;

    /// @dev Get implementation address.
    function implementation() internal view returns (address impl) {
        assembly { // solium-disable-line
            impl := sload(_IMPLEMENTATION_SLOT)
        }
    }

    /// @dev Set new implementation address.
    function setImplementation(address codeAddress) internal {
        assembly {
            // solium-disable-line
            sstore(
                _IMPLEMENTATION_SLOT,
                codeAddress
            )
        }
    }

}

File 15 of 17 : Proxy.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
 * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
 * be specified by overriding the virtual {_implementation} function.
 *
 * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
 * different contract through the {_delegate} function.
 *
 * The success and return data of the delegated call will be returned back to the caller of the proxy.
 */
abstract contract Proxy {
    /**
     * @dev Delegates the current call to `implementation`.
     *
     * This function does not return to its internall call site, it will return directly to the external caller.
     */
    function _delegate(address implementation) internal virtual {
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }

    /**
     * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
     * and {_fallback} should delegate.
     */
    function _implementation() internal view virtual returns (address);

    /**
     * @dev Delegates the current call to the address returned by `_implementation()`.
     *
     * This function does not return to its internall call site, it will return directly to the external caller.
     */
    function _fallback() internal virtual {
        _beforeFallback();
        _delegate(_implementation());
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
     * function in the contract matches the call data.
     */
    fallback () external payable virtual {
        _fallback();
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
     * is empty.
     */
    receive () external payable virtual {
        _fallback();
    }

    /**
     * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
     * call, or as part of the Solidity `fallback` or `receive` functions.
     *
     * If overriden should call `super._beforeFallback()`.
     */
    function _beforeFallback() internal virtual {
    }
}

File 16 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 17 of 17 : IERC777.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC777Token standard as defined in the EIP.
 *
 * This contract uses the
 * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
 * token holders and recipients react to token movements by using setting implementers
 * for the associated interfaces in said registry. See {IERC1820Registry} and
 * {ERC1820Implementer}.
 */
interface IERC777 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the smallest part of the token that is not divisible. This
     * means all token operations (creation, movement and destruction) must have
     * amounts that are a multiple of this number.
     *
     * For most token contracts, this value will equal 1.
     */
    function granularity() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by an account (`owner`).
     */
    function balanceOf(address owner) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * If send or receive hooks are registered for the caller and `recipient`,
     * the corresponding functions will be called with `data` and empty
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function send(address recipient, uint256 amount, bytes calldata data) external;

    /**
     * @dev Destroys `amount` tokens from the caller's account, reducing the
     * total supply.
     *
     * If a send hook is registered for the caller, the corresponding function
     * will be called with `data` and empty `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - the caller must have at least `amount` tokens.
     */
    function burn(uint256 amount, bytes calldata data) external;

    /**
     * @dev Returns true if an account is an operator of `tokenHolder`.
     * Operators can send and burn tokens on behalf of their owners. All
     * accounts are their own operator.
     *
     * See {operatorSend} and {operatorBurn}.
     */
    function isOperatorFor(address operator, address tokenHolder) external view returns (bool);

    /**
     * @dev Make an account an operator of the caller.
     *
     * See {isOperatorFor}.
     *
     * Emits an {AuthorizedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function authorizeOperator(address operator) external;

    /**
     * @dev Revoke an account's operator status for the caller.
     *
     * See {isOperatorFor} and {defaultOperators}.
     *
     * Emits a {RevokedOperator} event.
     *
     * Requirements
     *
     * - `operator` cannot be calling address.
     */
    function revokeOperator(address operator) external;

    /**
     * @dev Returns the list of default operators. These accounts are operators
     * for all token holders, even if {authorizeOperator} was never called on
     * them.
     *
     * This list is immutable, but individual holders may revoke these via
     * {revokeOperator}, in which case {isOperatorFor} will return false.
     */
    function defaultOperators() external view returns (address[] memory);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must
     * be an operator of `sender`.
     *
     * If send or receive hooks are registered for `sender` and `recipient`,
     * the corresponding functions will be called with `data` and
     * `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
     *
     * Emits a {Sent} event.
     *
     * Requirements
     *
     * - `sender` cannot be the zero address.
     * - `sender` must have at least `amount` tokens.
     * - the caller must be an operator for `sender`.
     * - `recipient` cannot be the zero address.
     * - if `recipient` is a contract, it must implement the {IERC777Recipient}
     * interface.
     */
    function operatorSend(
        address sender,
        address recipient,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the total supply.
     * The caller must be an operator of `account`.
     *
     * If a send hook is registered for `account`, the corresponding function
     * will be called with `data` and `operatorData`. See {IERC777Sender}.
     *
     * Emits a {Burned} event.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     * - the caller must be an operator for `account`.
     */
    function operatorBurn(
        address account,
        uint256 amount,
        bytes calldata data,
        bytes calldata operatorData
    ) external;

    event Sent(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256 amount,
        bytes data,
        bytes operatorData
    );

    event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);

    event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);

    event AuthorizedOperator(address indexed operator, address indexed tokenHolder);

    event RevokedOperator(address indexed operator, address indexed tokenHolder);
}

Settings
{
  "remappings": [],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"contract IWETH","name":"weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenDowngraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenUpgraded","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"downgradeToETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"downgradeToWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"initialAddress","type":"address"}],"name":"initializeProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"upgradeByETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"upgradeByETHTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"wad","type":"uint256"}],"name":"upgradeByWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60a060405234801561001057600080fd5b50604051610d61380380610d618339818101604052602081101561003357600080fd5b50516001600160601b0319606082901b166080526040518190610055906100a9565b6001600160a01b03909116815260405190819003602001906000f080158015610082573d6000803e3d6000fd5b50602080546001600160a01b0319166001600160a01b0392909216919091179055506100b6565b6101b380610bae83390190565b60805160601c610acc6100e2600039806102d35280610368528061067c52806107125250610acc6000f3fe6080604052600436106100595760003560e01c8063160e8be31461007057806328a96a591461009a5780634a0687ef146100c45780634c65c376146100f75780637687d19b14610121578063cf81464b1461014757610068565b366100685761006661014f565b005b61006661014f565b34801561007c57600080fd5b506100666004803603602081101561009357600080fd5b5035610169565b3480156100a657600080fd5b50610066600480360360208110156100bd57600080fd5b50356102a6565b3480156100d057600080fd5b50610066600480360360208110156100e757600080fd5b50356001600160a01b03166104d8565b34801561010357600080fd5b506100666004803603602081101561011a57600080fd5b50356105a4565b6100666004803603602081101561013757600080fd5b50356001600160a01b03166107c0565b6100666108e4565b610157610167565b6101676101626109f2565b610a1a565b565b6040805160008082526020820192839052639d87674160e01b83523360248301818152604484018690526060606485019081528451608486018190523096639d876741969495899594939260a4860192918190849084905b838110156101d95781810151838201526020016101c1565b50505050905090810190601f1680156102065780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561022757600080fd5b505af115801561023b573d6000803e3d6000fd5b505060405133925083156108fc02915083906000818181858888f1935050505015801561026c573d6000803e3d6000fd5b5060408051828152905133917f3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d919081900360200190a250565b604080516323b872dd60e01b81523360048201523060248201526044810183905290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916323b872dd9160648083019260209291908290030181600087803b15801561031b57600080fd5b505af115801561032f573d6000803e3d6000fd5b505050506040513d602081101561034557600080fd5b505060408051632e1a7d4d60e01b81526004810183905290516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691632e1a7d4d91602480830192600092919082900301818387803b1580156103af57600080fd5b505af11580156103c3573d6000803e3d6000fd5b5050604080516000808252602082019283905263c68d428360e01b835233602483018181526044840188905260606064850190815284516084860181905230985063c68d4283975092958995949293919260a4860192908190849084905b83811015610439578181015183820152602001610421565b50505050905090810190601f1680156104665780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561048757600080fd5b505af115801561049b573d6000803e3d6000fd5b50506040805184815290513393507f25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df92509081900360200190a250565b6001600160a01b038116610533576040805162461bcd60e51b815260206004820152601760248201527f5555505350726f78793a207a65726f2061646472657373000000000000000000604482015290519081900360640190fd5b600061053d610a3e565b6001600160a01b031614610598576040805162461bcd60e51b815260206004820152601e60248201527f5555505350726f78793a20616c726561647920696e697469616c697a65640000604482015290519081900360640190fd5b6105a181610a63565b50565b6040805160008082526020820192839052639d87674160e01b83523360248301818152604484018690526060606485019081528451608486018190523096639d876741969495899594939260a4860192918190849084905b838110156106145781810151838201526020016105fc565b50505050905090810190601f1680156106415780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561066257600080fd5b505af1158015610676573d6000803e3d6000fd5b505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156106d557600080fd5b505af11580156106e9573d6000803e3d6000fd5b50506040805163a9059cbb60e01b81523360048201526024810186905290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016945063a9059cbb9350604480830193506020928290030181600087803b15801561075b57600080fd5b505af115801561076f573d6000803e3d6000fd5b505050506040513d602081101561078557600080fd5b505060408051828152905133917f3bc27981aebbb57f9247dc00fde9d6cd91e4b230083fec3238fedbcba1f9ab3d919081900360200190a250565b604080516000808252602082019283905263c68d428360e01b83526001600160a01b038416602483019081523460448401819052606060648501908152845160848601819052309663c68d42839689969495909490939260a4860192918190849084905b8381101561083c578181015183820152602001610824565b50505050905090810190601f1680156108695780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b15801561088a57600080fd5b505af115801561089e573d6000803e3d6000fd5b50506040805134815290516001600160a01b03851693507f25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df92509081900360200190a250565b604080516000808252602082019283905263c68d428360e01b835233602483018181523460448501819052606060648601908152855160848701819052309763c68d42839795969395949360a4860192908190849084905b8381101561095457818101518382015260200161093c565b50505050905090810190601f1680156109815780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156109a257600080fd5b505af11580156109b6573d6000803e3d6000fd5b50506040805134815290513393507f25ca84076773b0455db53621c459ddc84fe40840e4932a62706a032566f399df92509081900360200190a2565b60003615610a0957610a02610a87565b9050610a17565b506020546001600160a01b03165b90565b3660008037600080366000845af43d6000803e808015610a39573d6000f35b3d6000fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b6000610a91610a3e565b90509056fea2646970667358221220d9b2e23bae0b0272cea4042ec6193d53184c8e8eadf3810ba97d7dff8e71b10964736f6c6343000706003360a060405234801561001057600080fd5b506040516101b33803806101b38339818101604052602081101561003357600080fd5b5051606081901b6001600160601b0319166080526001600160a01b031661014d610066600039806014525061014d6000f3fe60806040523661011257336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461011057604080516000808252602082019283905263c68d428360e01b835233602483018181523460448501819052606060648601908152855160848701819052309763c68d42839795969395949360a4860192908190849084905b838110156100a9578181015183820152602001610091565b50505050905090810190601f1680156100d65780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156100f757600080fd5b505af115801561010b573d6000803e3d6000fd5b505050505b005b600080fdfea264697066735822122013e2a52bb5b9c6ce36580c73a47c8f65953e7402d70a64b553a7d46cb7ac38f664736f6c634300070600330000000000000000000000000000000000000000000000000000000000000000

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : weth (address): 0x0000000000000000000000000000000000000000

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading