Reputation and Scoring in EthicHub

in #blockchain6 years ago

Hello there, this is Raúl, Tech Node at EthicHub.

1 AxD2vPaIw9xK5PeFD5achA.png

We are building a line of trust between agricultural communities in developing countries and lenders all around the globe. How are we doing that?

Well, it helps that the lending model we are going to use is not new, being used by communities around the world for decades.

Communities working together

First, the credits are provided to communities, whose members elected themselves and were responsible to repay the credit as one entity.

The problem they have is there are no previous records of the work done, even if they have been doing this for years. How do you know if they can repay you? How much?

To establish trust, the first credit is offered later in the production process, to harvest the coffee. This way the money is going to be converted soon to coffee, which in turn is sold to a third party commercializer, reducing risks and allowing us to measure the production capacity and creditworthiness of the community and each individual, along with the capacity to undertake bigger enterprises.

An added benefit of this is we can help them to sell better and improve their administrative capacities, a task that will be one of EthicHub’s local nodes responsibilities.

In order to model this system built over the trust that come from working together over the years to the rest of the world, we need to build reputation system for EthicHub’s communities and the Local Nodes that helps them.

Modeling project impact

To have a measure of the impact of a project, we propose classifying them in 5 Tiers (t1 to t5). Each tier corresponds to the monetary amount lent per person in the project. Since each country will have a different monetary amount per person that makes sense for each tier, we will not use the actual monetary value for reputation calculations.

1 p60ukzi8LsLTqmX4nLP8Iw.png

New communities will start in Tier1, and will have access to the next tiers if they prove their trustworthiness (reputation) and the Local Nodes verify their production capacity.

So for each project:

0 mU-GjhUeQLoSievE.png

Pa → Project amount
tn → tier value
C → number of members the community that will work in the project.

For illustration purposes, these are the tiers for México according to our team’s experience and research there:

Tier1: 1000 per person.
Tier2: 2000 per person.
Tier3: 5000 per person.
Tier4: 10000 per person.
Tier5: 20000 per person.

The minimum community size will be of 20 people.

Modeling reputation

0 5lVkBmS1KjSN-qIw.jpg

We decided tho use a general score of from 0 to 10, starting with 5.

We have to be careful designing the progression of this values,since we are rating people, not things or resources.

Thus, the progression to increase or decrease reputation score won’t be the same.

Who determines the scores?

By all means, using “voting” reputation systems (think Amazon stars) to build trust is not easy or that effective.

¨So even in the absence of explicit gaming, peer-to-peer internet reputation systems do not solve the problem of trust.¨ 
— Tom Slee, Some Obvious Things About Internet Reputation Systems

We want this score to measure the “payment experience” of the credit, not the subjective votes of investors, so after each lending smart contract is paid or declared default, our Reputation smart contract will execute according to our algorithm to update the reputations as defined.


//...

contract EthicHubLending is EthicHubBase, Ownable, Pausable {

    //...
    
    // In this moment, when the borrower returns the money, we evaluate how "well" they paid.
    function returnBorrowedEth() payable public {
        require(state == LendingState.AwaitingReturn);
        require(borrowerReturnEthPerFiatRate > 0);
        bool projectRepayed = false;
        uint excessRepayment = 0;
        uint newReturnedEth = 0;
        emit onReturnAmount(msg.sender, msg.value);
        (newReturnedEth, projectRepayed, excessRepayment) = calculatePaymentGoal(
                                                                                    borrowerReturnAmount(),
                                                                                    returnedEth,
                                                                                    msg.value);
        returnedEth = newReturnedEth;
        if (projectRepayed == true) {
            state = LendingState.ContributionReturned;
            emit StateChange(uint(state));
            updateReputation();
        }
        if (excessRepayment > 0) {
            msg.sender.transfer(excessRepayment);
        }
    }

    //First we calculate how many days over the pre-established days to return the funds.
    //If they are in the default period, the reputations will be decreased, if not incremented.
    function updateReputation() internal {
        uint defaultDays = getDefaultDays(now);
        if (defaultDays > 0) {
            ethicHubStorage.setUint(keccak256("lending.defaultDays", this), defaultDays);
            reputation.burnReputation();
        } else {
            uint successesByTier = ethicHubStorage.getUint(keccak256("community.completedProjectsByTier", this, tier)).add(1);
            ethicHubStorage.setUint(keccak256("community.completedProjectsByTier", this, tier), successesByTier);
            reputation.incrementReputation();
        }
    }
    
    function getDelayDays(uint date) public view returns(uint) {
        uint lendingDaysSeconds = lendingDays * 1 days;
        uint defaultTime = fundingEndTime.add(lendingDaysSeconds);
        if (date < defaultTime) {
            return 0;
        } else {
            return date.sub(defaultTime).div(60).div(60).div(24);
        }
    }
    
    //This is to declare the maximum penalty, if funds are not returned after the maximum default days established.
    function declareProjectDefault() external onlyOwnerOrLocalNode {
        require(state == LendingState.AwaitingReturn);
        uint maxDelayDays = ethicHubStorage.getUint(keccak256("lending.maxDelayDays", this));
        require(getDelayDays(now) >= maxDelayDays);
        ethicHubStorage.setUint(keccak256("lending.delayDays", this), maxDelayDays);
        reputation.burnReputation(maxDelayDays);
        state = LendingState.Default;
        emit StateChange(uint(state));
    }
} 

Full code in https://github.com/EthicHub/platform-contracts/tree/develop

Communities

1 lRx2Q6zSxgAM_ebZLTgqNw.png

In the first version of the platform, the reputation of the community that asks for a credit will be measure as a whole.

Future developments will allow to have a rating of each individual.

Decrease in reputation scoring

In this area,the only factor is of how late is the community returning the funds.

1 -LOsl3PXW79EOoF_XKw1QA.png

Rc → Community reputation.
Rcp → Previous community reputation.
d → Days in default (over the established return period).
dmax → Max days in default allowed.

For example, if we set a dmax of 90 days, the community will lose a 0.9% of their reputation per day.

It’s possible to lose all the reputation by having a default. We understand this could happen by external causes or disasters, and the mechanisms for a community to “go back” in the system is left for future developments, and will involve a Local Node’s staking her reputation by vouching for them.

Increase in reputation

0 X-QGddtAkeQD5xhj.png

Rc → Reputation of a community.
Rcp → Previous reputation of a community.
Ntn→ number of successful projects in the same tier.

How will the progression of a community look (assuming no defaulted projects) ?

1 0R8tLgNoPBxBil_lDFuzGA.png1 I5sBGA9MogE8OKc5Ej2A8g.png

As Jori Armbruster (EthicHub’s Coordinator Node) wrote in Breaking the Poverty Cycle:

¨ The main tool to break free from [the poverty cycle] is to provide access to reasonable interest rate loans for increasing productivity to such an extent they are capable of both things: paying such debt and investing again to raise such productivity.¨

We want our scoring progression system to reflect that idea, encouraging the communities and local node to increase their capabilities.

Local Nodes

1 xI6bD7sn77NXbZ7wwmlOKA.png

The Local Node’s score will reflect how well they are doing, so their reputation has to be tied to that of the communities they manage.

The bigger and better the projects, the fastest his reputation will grow.

If a community fails to repay a project, the Local Node will lose 1 point max. With this, we want to encourage the Local Nodes to manage numerous communities (spreading their risk).

Decrease in reputation

1 hdSxuYQ4DT2piZqB6_mmpw.png

Dln → Decrement in reputation for the Local Node.
Rlnp → Previous Local Node’ reputation.
d → delay in days (over the established return period).
dmax → Max delay allowed until declaring default (in days).

1 unGjk_3IBHS4eLyj9Wx_Mg.png

Rln → Local Node’s reputation.

Increase in reputation

0 OzTXQQlnbpyYwlo2.png

Rln → Local Node’s reputation.
Rlnp → Local Node’s previous reputation.
Tmn → multiplier for project Tier (t1 is 1, t2 is 2, etc).
C → number of members in the community for the successful project.

Show me the code!


import '../EthicHubBase.sol';
import '../math/SafeMath.sol';
import './EthicHubReputationInterface.sol';

contract EthicHubReputation is EthicHubBase, EthicHubReputationInterface {

    //10 with 2 decilmals
    uint maxReputation = 1000;
    uint reputationStep = 100;
    //Tier 1 x 20 people
    uint minProyect = 20;
    uint constant public initReputation = 500;
    //0.05
    uint incrLocalNodeMultiplier = 5; 
 
    //
    //.....
    //
    
    function incrementCommunityReputation(uint previousReputation, uint completedProjectsByTier) view returns(uint) {
        require(completedProjectsByTier > 0);
        uint nextRep = previousReputation.add(reputationStep / completedProjectsByTier);
        if (nextRep >= maxReputation) {
            return maxReputation;
        } else {
            return nextRep;
        }
    }

    function incrementLocalNodeReputation(uint previousReputation, uint tier, uint borrowers) view returns(uint) {
        uint increment = (tier.mul(borrowers).div(minProyect)).mul(incrLocalNodeMultiplier);
        uint nextRep = previousReputation.add(increment);
        if (nextRep >= maxReputation) {
            return maxReputation;
        } else {
            return nextRep;
        }
    }

    function burnLocalNodeReputation(uint delayDays, uint maxDelayDays, uint prevReputation) view returns(uint) {
        if (delayDays >= maxDelayDays){
            return 0;
        }
        uint decrement = prevReputation.mul(delayDays).div(maxDelayDays);
        if (delayDays < maxDelayDays && decrement < reputationStep) {
            return prevReputation.sub(decrement);
        } else {
            return prevReputation.sub(reputationStep);
        }
    }

    function burnCommunityReputation(uint delayDays, uint maxDelayDays, uint prevReputation) pure returns(uint) {
        if (delayDays < maxDelayDays) {
            return prevReputation.sub(prevReputation.mul(delayDays).div(maxDelayDays));
        } else {
            return 0;
        }
    }
}

Full code in https://github.com/EthicHub/platform-contracts/tree/develop

Presenting this to the investor.

There is a problem when presenting scores as a single number, with let’s say a star rating. If you enter the platform and see this, what would you think?

0 ADsS3NQ1no75w-ln.png

So, if a community pays perfectly well 5 Tier1 projects, should they be perceived as “not trustworthy”? We think not, so a more nuanced system should take in account the previous experience in that tier when presenting the community to the investors.

We are working on refining the visual metaphor of our MVP before our tokensale in September, including our community’s suggestions.

How? Find out in the next article.

Join our community to stay up to date

Join our Telegram group
Join our Newsletter
Follow us on Reddit
Follow us on Twitter

1 pdMgwbkyI0-hzIz-ElGi3A.png

Sort:  

Congratulations @ethichub! You have completed some achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes received

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!