# Linear optimization problem bounty

This contract implements a bounty for solving linear optimization problems.

An example problem is defined in the contracts `_calculateNewSolution(x1: uint256, x2: uint256)` method:

``````def _calculateNewSolution(_x1: uint256, _x2: uint256) -> uint256:
assert x1 <= 40
assert x2 <= 35
assert (3 * x1) + (2 * x2) <= 200
assert x1 + x2 <= 120
assert x1 > 0 and x2 > 0
# calculate and return new solution
return (4 * x1) + (6 * x2)``````

### How it works

Users can submit solutions using the `submitSolution(_x1: uint256, _x2: uint256)` method. The contract checks the submitted values against the problems constraints and saves/rejects them depending on whether the solution respects all of them. When the end of the competition is reached, the address that submitted the best solution can call `claimBounty()` to claim the Ether that is locked in the contract.

### Implementation in Vyper

linear_optimization_problem_bounty.vy
``````# Author: Sören Steiger, twitter.com/ssteiger_

# EVENTS:
BountyIncreased: event({_amount: wei_value})
CompetitionTimeExtended: event({_to: uint256})

# STATE VARIABLES:

x1: public(uint256)
x2: public(uint256)

bestSolution: public(uint256)

durationInBlocks: public(uint256)
competitionEnd: public(uint256)
claimPeriodeLength: public(uint256)

# METHODS:
@public
def __init__(_durationInBlocks: uint256):
self.owner = msg.sender
self.bestSolution = 0
self.durationInBlocks = _durationInBlocks
self.competitionEnd = block.number + _durationInBlocks
# set claim periode to three days
# assuming an average blocktime of 14 seconds -> 86400/14
self.claimPeriodeLength = 6172

@public
@payable
def __default__():
# return any funds sent to the contract address directly
send(msg.sender, msg.value)

@private
def _calculateNewSolution(_x1: uint256, _x2: uint256) -> uint256:
# check new parameters against constraints
assert _x1 <= 8
assert _x2 <= 12
assert (3 * _x1) + (2 * _x2) <= 100
assert _x1 + _x2 <= 24
assert _x1 > 0 and _x2 > 0
# calculate and return new solution
return (3 * _x1) + (2 * _x2)

@public
def submitSolution(_x1: uint256, _x2: uint256) -> uint256:
newSolution: uint256
newSolution = self._calculateNewSolution(_x1, _x2)
assert newSolution > self.bestSolution
# save the solution and it's values
self.x1 = _x1
self.x2 = _x2
self.bestSolution = newSolution
log.NewSolutionFound(msg.sender, newSolution)
return newSolution

@public
def claimBounty():
assert block.number > self.competitionEnd
# no solution was found -> extend duration of competition
self.competitionEnd = block.number + self.durationInBlocks
else:
assert block.number < (self.competitionEnd + self.claimPeriodeLength)
# extend duration of competition
self.competitionEnd = block.number + self.durationInBlocks

@public
@payable
def topUpBounty():
log.BountyIncreased(msg.value)

@public
def extendCompetition():
# only if no valid solution has been submitted