contract LotteryStorageStub {
    // =============== LotteryStorage contract's storage ================ //

    // --------- Slot --------- //

    // The Lottery address that this storage belongs to.
    // Is set by the "initialize()", called by corresponding Lottery.
    address lottery;

    // The Random Seed, that was passed to us from Randomness Provider,
    // or generated alternatively.
    uint64 randomSeed;

    // The actual number of winners that there will be. Set after
    // completing the Winner Selection Algorithm.
    uint16 numberOfWinners;

    // Bool indicating if Winner Selection Algorithm has been executed.
    bool algorithmCompleted;


    // --------- Slot --------- //

    // Winner Algorithm config. Specified in Initialization().
    LotteryStorage.WinnerAlgorithmConfig algConfig;

    // --------- Slot --------- //

    // The Min-Max holder score storage.
    LotteryStorage.MinMaxHolderScores minMaxScores;

    // --------- Slot --------- //

    // Array of holders.
    address[] /*public*/ holders;

    // --------- Slot --------- //

    // Holder array indexes mapping, for O(1) array element access.
    mapping( address => uint ) holderIndexes;

    // --------- Slot --------- //

    // Mapping of holder data.
    mapping( address => LotteryStorage.HolderData ) /*public*/ holderData;

    // --------- Slot --------- //

    // Mapping of referral IDs to addresses of holders who generated
    // those IDs.
    mapping( uint256 => address ) referrers;

    // --------- Slot --------- //

    // The array of final-sorted winners (set after Winner Selection
    // Algorithm completes), that contains the winners' indexes
    // in the "holders" array, to save space.
    //
    // Notice that by using uint16, we can fit 16 items into one slot!
    // So, if there are 160 winners, we only take up 10 slots, so
    // only 20,000 * 10 = 200,000 gas gets consumed!
    //
    LotteryStorage.WinnerIndexStruct[] sortedWinnerIndexes;


    // =================== OUR CONTRACT'S OWN STORAGE =================== //

    // The address of the delegate contract, containing actual logic.
    address public __delegateContract;


    // ===================          Functions         =================== //


    // Constructor.
    // Just set the delegate's address.
    function stub_construct( address _delegateAddr )
                                                                external
    {
        require( __delegateContract == address(0) );
        __delegateContract = _delegateAddr;
    }


    // Fallback function, which delegates any call to our
    // contract, into the delegate contract.
    fallback()
                external
    {
        // DelegateCall the delegate code contract.
        ( bool success, bytes memory data ) =
            __delegateContract.delegatecall( msg.data );

        // Use inline assembly to be able to return value from the fallback.
        // (by default, returning a value from fallback is not possible,
        // but it's still possible to manually copy data to the
        // return buffer.
        assembly
        {
            // delegatecall returns 0 (false) on error.
            // Add 32 bytes to "data" pointer, because first slot (32 bytes)
            // contains the length, and we use return value's length
            // from returndatasize() opcode.
            switch success
                case 0  { revert( add( data, 32 ), returndatasize() ) }
                default { return( add( data, 32 ), returndatasize() ) }
        }
    }
}
/**
 *  LotteryStorage contract's storage-stub.
 *  Uses delagate calls to execute actual code on this contract's behalf.
 */
function stub_construct( address _delegateAddr )
                                                            external
{
    require( __delegateContract == address(0) );
    __delegateContract = _delegateAddr;
}

// ===================          Functions         =================== //
// Constructor.
// Just set the delegate's address.