ETH Price: $2,627.83 (-5.37%)

Contract

0xCbbE0C0454f3379eA8B0FBC8Cf976a54154937c2
 

Overview

ETH Balance

0.01 ETH

Eth Value

$26.28 (@ $2,627.83/ETH)

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Claim81662682019-07-17 4:46:332033 days ago1563338793IN
0xCbbE0C04...4154937c2
0 ETH0.0006699620
Claim81648092019-07-16 23:25:002033 days ago1563319500IN
0xCbbE0C04...4154937c2
0 ETH0.0008703820
Claim81648012019-07-16 23:24:122033 days ago1563319452IN
0xCbbE0C04...4154937c2
0 ETH0.0006699620
Claim81570162019-07-15 17:54:462034 days ago1563213286IN
0xCbbE0C04...4154937c2
0 ETH0.000100493
Claim81542552019-07-15 7:27:162035 days ago1563175636IN
0xCbbE0C04...4154937c2
0 ETH0.000110543.3
Finalize81536792019-07-15 5:16:272035 days ago1563167787IN
0xCbbE0C04...4154937c2
0 ETH0.000326083
Transfer76495072019-04-27 12:34:312114 days ago1556368471IN
0xCbbE0C04...4154937c2
0.01 ETH0.000121622.5
Transfer75963422019-04-19 5:45:012122 days ago1555652701IN
0xCbbE0C04...4154937c2
2 ETH0.000227238
Transfer75929342019-04-18 17:10:342122 days ago1555607434IN
0xCbbE0C04...4154937c2
0.01 ETH0.000145953
Transfer75516602019-04-12 6:57:342129 days ago1555052254IN
0xCbbE0C04...4154937c2
0.2 ETH0.0006713813.8
Transfer75484902019-04-11 19:01:302129 days ago1555009290IN
0xCbbE0C04...4154937c2
0.128 ETH0.000437859
Transfer75460542019-04-11 9:53:442130 days ago1554976424IN
0xCbbE0C04...4154937c2
0.01 ETH0.000318255

Latest 4 internal transactions

Advanced mode:
Parent Transaction Hash Block
From
To
81662682019-07-17 4:46:332033 days ago1563338793
0xCbbE0C04...4154937c2
2.2 ETH
81648012019-07-16 23:24:122033 days ago1563319452
0xCbbE0C04...4154937c2
0.128 ETH
81570162019-07-15 17:54:462034 days ago1563213286
0xCbbE0C04...4154937c2
0.01 ETH
81542552019-07-15 7:27:162035 days ago1563175636
0xCbbE0C04...4154937c2
0.01 ETH
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xdC4c1B5f...8B76164E9
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
CharityChallenge

Compiler Version
v0.5.0+commit.1d4f565a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion
/**
 *Submitted for verification at Etherscan.io on 2019-04-22
*/

pragma solidity ^0.5.0;

interface IMarket {
    function isFinalized() external view returns (bool);
    function isInvalid() external view returns (bool);
    function getWinningPayoutNumerator(uint256 _outcome) external view returns (uint256);
    function getEndTime() external view returns (uint256);
}
contract CharityChallenge {

    event Received(address indexed sender, uint256 value);

    event Donated(address indexed npo, uint256 value);

    event Claimed(address indexed claimer, uint256 value);

    event SafetyHatchClaimed(address indexed claimer, uint256 value);

    string public constant VERSION = "0.3.0";

    address payable public contractOwner;

    // key is npo address, value is ratio
    mapping(address => uint8) public npoRatios;

    uint8 sumRatio;

    address payable[] public npoAddresses;

    address public marketAddress;

    bool public unlockOnNo;

    IMarket market;

    uint256 public challengeEndTime;

    uint256 public challengeSafetyHatchTime1;

    uint256 public challengeSafetyHatchTime2;

    // Valid outcomes are 'YES', 'NO' and 'INVALID'
    bool public isEventFinalized;

    // hasChallengeAccomplished will be set to true if we got the expected
    // result that allow to unlock the funds.
    bool public hasChallengeAccomplished;

    bool private safetyHatchClaimSucceeded;

    mapping(address => uint256) public donorBalances;

    uint256 public donorCount;

    bool private mReentrancyLock = false;
    modifier nonReentrant() {
        require(!mReentrancyLock);
        mReentrancyLock = true;
        _;
        mReentrancyLock = false;
    }

    constructor(
        address payable _contractOwner,
        address payable[] memory _npoAddresses,
        uint8[] memory _ratios,
        address _marketAddress,
        bool _unlockOnNo
    ) public
    {
        require(_npoAddresses.length == _ratios.length);
        uint length = _npoAddresses.length;
        for (uint i = 0; i < length; i++) {
            address payable npo = _npoAddresses[i];
            npoAddresses.push(npo);
            require(_ratios[i] > 0, "Ratio must be a positive number");
            npoRatios[npo] = _ratios[i];
            sumRatio += _ratios[i];
        }
        contractOwner = _contractOwner;
        marketAddress = _marketAddress;
        market = IMarket(_marketAddress);
        unlockOnNo = _unlockOnNo;
        challengeEndTime = market.getEndTime();
        challengeSafetyHatchTime1 = challengeEndTime + 26 weeks;
        challengeSafetyHatchTime2 = challengeSafetyHatchTime1 + 52 weeks;
        isEventFinalized = false;
        hasChallengeAccomplished = false;
    }

    function() external payable {
        require(now <= challengeEndTime);
        require(msg.value > 0);
        if (donorBalances[msg.sender] == 0 && msg.value > 0) {
            donorCount++;
        }
        donorBalances[msg.sender] += msg.value;
        emit Received(msg.sender, msg.value);
    }

    function balanceOf(address _donorAddress) public view returns (uint256) {
        if (safetyHatchClaimSucceeded) {
            return 0;
        }
        return donorBalances[_donorAddress];
    }

    function finalize() nonReentrant external {
        require(now > challengeEndTime);
        require(now <= challengeSafetyHatchTime1);
        require(!isEventFinalized);
        doFinalize();
    }

    function doFinalize() private {
        bool hasError;
        (hasChallengeAccomplished, hasError) = checkAugur();
        if (!hasError) {
            isEventFinalized = true;
            if (hasChallengeAccomplished) {
                uint256 totalContractBalance = address(this).balance;
                uint length = npoAddresses.length;
                uint256 donatedAmount = 0;
                for (uint i = 0; i < length - 1; i++) {
                    address payable npo = npoAddresses[i];
                    uint8 ratio = npoRatios[npo];
                    uint256 amount = totalContractBalance * ratio / sumRatio;
                    donatedAmount += amount;
                    npo.transfer(amount);
                    emit Donated(npo, amount);
                }
                // Don't want to keep any amount in the contract
                uint256 remainingAmount = totalContractBalance - donatedAmount;
                address payable npo = npoAddresses[length - 1];
                npo.transfer(remainingAmount);
                emit Donated(npo, remainingAmount);
            }
        }
    }

    function getExpectedDonationAmount(address payable _npo) view external returns (uint256) {
        require(npoRatios[_npo] > 0);
        uint256 totalContractBalance = address(this).balance;
        uint8 ratio = npoRatios[_npo];
        uint256 amount = totalContractBalance * ratio / sumRatio;
        return amount;
    }

    function claim() nonReentrant external {
        require(now > challengeEndTime);
        require(isEventFinalized || now > challengeSafetyHatchTime1);
        require(!hasChallengeAccomplished || now > challengeSafetyHatchTime1);
        require(balanceOf(msg.sender) > 0);

        uint256 claimedAmount = balanceOf(msg.sender);
        donorBalances[msg.sender] = 0;
        msg.sender.transfer(claimedAmount);
        emit Claimed(msg.sender, claimedAmount);
    }

    function safetyHatchClaim() external {
        require(now > challengeSafetyHatchTime2);
        require(msg.sender == contractOwner);

        uint totalContractBalance = address(this).balance;
        safetyHatchClaimSucceeded = true;
        contractOwner.transfer(address(this).balance);
        emit SafetyHatchClaimed(contractOwner, totalContractBalance);
    }

    function checkAugur() private view returns (bool happened, bool errored) {
        if (market.isFinalized()) {
            if (market.isInvalid()) {
                // Treat 'invalid' outcome as 'no'
                // because 'invalid' is one of the valid outcomes
                return (false, false);
            } else {
                uint256 no = market.getWinningPayoutNumerator(0);
                uint256 yes = market.getWinningPayoutNumerator(1);
                if (unlockOnNo) {
                    return (yes < no, false);
                }
                return (yes > no, false);
            }
        } else {
            return (false, true);
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[],"name":"safetyHatchClaim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"npoAddresses","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"hasChallengeAccomplished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finalize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"claim","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"npoRatios","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_npo","type":"address"}],"name":"getExpectedDonationAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_donorAddress","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"donorBalances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"challengeSafetyHatchTime1","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"marketAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isEventFinalized","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"unlockOnNo","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"challengeEndTime","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"donorCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"contractOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"challengeSafetyHatchTime2","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_contractOwner","type":"address"},{"name":"_npoAddresses","type":"address[]"},{"name":"_ratios","type":"uint8[]"},{"name":"_marketAddress","type":"address"},{"name":"_unlockOnNo","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"npo","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Donated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"claimer","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"claimer","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"SafetyHatchClaimed","type":"event"}]

Deployed Bytecode

0x6080604052600436106100fc576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806307171d7f146102205780630ed7e49914610237578063306a7ce0146102b25780634bb278f3146102e15780634e71d92d146102f85780635ead3d4b1461030f5780635f95eb4d1461037a57806370a08231146103df5780637b8c8de11461044457806387730309146104a957806395623641146104d4578063b77309d61461052b578063ba7fd2fb1461055a578063bc3fde4e14610589578063c407670f146105b4578063ce606ee0146105df578063d87a328a14610636578063ffa1ad7414610661575b600654421115151561010d57600080fd5b60003411151561011c57600080fd5b6000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414801561016b5750600034115b1561018357600b600081548092919060010191905055505b34600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f88525874346040518082815260200191505060405180910390a2005b34801561022c57600080fd5b506102356106f1565b005b34801561024357600080fd5b506102706004803603602081101561025a57600080fd5b8101908080359060200190929190505050610884565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156102be57600080fd5b506102c76108c2565b604051808215151515815260200191505060405180910390f35b3480156102ed57600080fd5b506102f66108d5565b005b34801561030457600080fd5b5061030d61096e565b005b34801561031b57600080fd5b5061035e6004803603602081101561033257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b20565b604051808260ff1660ff16815260200191505060405180910390f35b34801561038657600080fd5b506103c96004803603602081101561039d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610b40565b6040518082815260200191505060405180910390f35b3480156103eb57600080fd5b5061042e6004803603602081101561040257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610c3e565b6040518082815260200191505060405180910390f35b34801561045057600080fd5b506104936004803603602081101561046757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610ca6565b6040518082815260200191505060405180910390f35b3480156104b557600080fd5b506104be610cbe565b6040518082815260200191505060405180910390f35b3480156104e057600080fd5b506104e9610cc4565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561053757600080fd5b50610540610cea565b604051808215151515815260200191505060405180910390f35b34801561056657600080fd5b5061056f610cfd565b604051808215151515815260200191505060405180910390f35b34801561059557600080fd5b5061059e610d10565b6040518082815260200191505060405180910390f35b3480156105c057600080fd5b506105c9610d16565b6040518082815260200191505060405180910390f35b3480156105eb57600080fd5b506105f4610d1c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561064257600080fd5b5061064b610d41565b6040518082815260200191505060405180910390f35b34801561066d57600080fd5b50610676610d47565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156106b657808201518184015260208101905061069b565b50505050905090810190601f1680156106e35780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6008544211151561070157600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561075c57600080fd5b60003073ffffffffffffffffffffffffffffffffffffffff163190506001600960026101000a81548160ff0219169083151502179055506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc3073ffffffffffffffffffffffffffffffffffffffff16319081150290604051600060405180830381858888f19350505050158015610811573d6000803e3d6000fd5b506000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f1ac1e39f5a410afcc9fd213aab1b92287e00cf00e216f3776f352ab328d124f9826040518082815260200191505060405180910390a250565b60038181548110151561089357fe5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600960019054906101000a900460ff1681565b600c60009054906101000a900460ff161515156108f157600080fd5b6001600c60006101000a81548160ff0219169083151502179055506006544211151561091c57600080fd5b600754421115151561092d57600080fd5b600960009054906101000a900460ff1615151561094957600080fd5b610951610d80565b6000600c60006101000a81548160ff021916908315150217905550565b600c60009054906101000a900460ff1615151561098a57600080fd5b6001600c60006101000a81548160ff021916908315150217905550600654421115156109b557600080fd5b600960009054906101000a900460ff16806109d1575060075442115b15156109dc57600080fd5b600960019054906101000a900460ff1615806109f9575060075442115b1515610a0457600080fd5b6000610a0f33610c3e565b111515610a1b57600080fd5b6000610a2633610c3e565b90506000600a60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610ab3573d6000803e3d6000fd5b503373ffffffffffffffffffffffffffffffffffffffff167fd8138f8a3f377c5259ca548e70e4c2de94f129f5a11036a15b69513cba2b426a826040518082815260200191505060405180910390a2506000600c60006101000a81548160ff021916908315150217905550565b60016020528060005260406000206000915054906101000a900460ff1681565b600080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1660ff16111515610b9f57600080fd5b60003073ffffffffffffffffffffffffffffffffffffffff163190506000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1690506000600260009054906101000a900460ff1660ff168260ff168402811515610c3057fe5b049050809350505050919050565b6000600960029054906101000a900460ff1615610c5e5760009050610ca1565b600a60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490505b919050565b600a6020528060005260406000206000915090505481565b60075481565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600960009054906101000a900460ff1681565b600460149054906101000a900460ff1681565b60065481565b600b5481565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60085481565b6040805190810160405280600581526020017f302e332e3000000000000000000000000000000000000000000000000000000081525081565b6000610d8a611066565b600960018294508391906101000a81548160ff0219169083151502179055505050801515611063576001600960006101000a81548160ff021916908315150217905550600960019054906101000a900460ff16156110625760003073ffffffffffffffffffffffffffffffffffffffff1631905060006003805490509050600080905060008090505b60018303811015610f7e576000600382815481101515610e2f57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1690506000600260009054906101000a900460ff1660ff168260ff168802811515610ed157fe5b04905080850194508273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610f1f573d6000803e3d6000fd5b508273ffffffffffffffffffffffffffffffffffffffff167f2a01595cddf097c90216094025db714da3f4e5bd8877b56ba86a24ecead8e543826040518082815260200191505060405180910390a25050508080600101915050610e13565b50600081840390506000600360018503815481101515610f9a57fe5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166108fc839081150290604051600060405180830381858888f1935050505015801561100d573d6000803e3d6000fd5b508073ffffffffffffffffffffffffffffffffffffffff167f2a01595cddf097c90216094025db714da3f4e5bd8877b56ba86a24ecead8e543836040518082815260200191505060405180910390a250505050505b5b50565b600080600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16638d4e40836040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156110ed57600080fd5b505afa158015611101573d6000803e3d6000fd5b505050506040513d602081101561111757600080fd5b8101908080519060200190929190505050156113d057600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166304be2f506040518163ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040160206040518083038186803b1580156111b157600080fd5b505afa1580156111c5573d6000803e3d6000fd5b505050506040513d60208110156111db57600080fd5b8101908080519060200190929190505050156111fd57600080915091506113d9565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c26482060006040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505060206040518083038186803b15801561128f57600080fd5b505afa1580156112a3573d6000803e3d6000fd5b505050506040513d60208110156112b957600080fd5b810190808051906020019092919050505090506000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633c26482060016040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082815260200191505060206040518083038186803b15801561135e57600080fd5b505afa158015611372573d6000803e3d6000fd5b505050506040513d602081101561138857600080fd5b81019080805190602001909291905050509050600460149054906101000a900460ff16156113c05781811060009350935050506113d9565b81811160009350935050506113d9565b60006001915091505b909156fea165627a7a723058204ac1f4163e7c7b9317c940ac5d0a1537465ff682c21bff3728939e011ef4e5bc0029

Swarm Source

bzzr://4ac1f4163e7c7b9317c940ac5d0a1537465ff682c21bff3728939e011ef4e5bc

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.