Skip to content

Instantly share code, notes, and snippets.

@deemru
Created February 14, 2025 08:17
Show Gist options
  • Save deemru/f60eeabfb0bf54f3377b5353b596097d to your computer and use it in GitHub Desktop.
Save deemru/f60eeabfb0bf54f3377b5353b596097d to your computer and use it in GitHub Desktop.
WAVES DEFI NODE
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let WAVES = unit
let PRECISION = 1_000_000_000_000_000
let kNODE = "NODE"
let kLEASEID = "LEASEID"
let kLEASED = "LEASED"
let kRATED = "RATED"
let NODE = this.getStringValue( kNODE ).addressFromStringValue()
let NODE_CLAIM = invoke( NODE, "claim", [], [] )
let NOLEASEID = base58''
let LEASEID = this.getBinary( kLEASEID ).valueOrElse( NOLEASEID )
let LEASED = this.getInteger( kLEASED ).valueOrElse( 0 )
func userRated( user: String ) = this.getInteger( user ).valueOrElse( 0 )
func userRatedUpdate( user: String, change: Int ) =
{
let result = userRated( user ) + change
if( result < 0 ) then throw( "userRatedUpdate(): result < 0" ) else
if( result == 0 ) then
DeleteEntry( user )
else
IntegerEntry( user, result )
}
let TOTAL_RATED = userRated( kRATED )
func totalRatedUpdate( change: Int ) = userRatedUpdate( kRATED, change )
let NODE_TOTAL = wavesBalance( NODE ).available
let NODE_MINIMAL = 10_0000_0000
let NODE_AVAILABLE = if( NODE_TOTAL <= NODE_MINIMAL ) then 0 else NODE_TOTAL - NODE_MINIMAL
let THIS_AVAILABLE = wavesBalance( this ).available
func RATE( correction: Int ) =
{
let total_waves = NODE_AVAILABLE + THIS_AVAILABLE - correction + LEASED
if( TOTAL_RATED == 0 ) then PRECISION else fraction( total_waves, PRECISION, TOTAL_RATED )
}
func sync( target_amount: Int ) =
{
strict before = THIS_AVAILABLE
strict claim = if( NODE_AVAILABLE > 0 ) then NODE_CLAIM else []
let after = wavesBalance( this ).available
if( NODE_AVAILABLE != after - before ) then throw( "sync(): NODE_AVAILABLE != after - before" ) else
let leased_new = LEASED + after - target_amount
if( leased_new == LEASED ) then [] else
if( leased_new < 0 ) then throw( "sync(): leased_new < 0" ) else
let leaseCancel = if( LEASEID == NOLEASEID ) then [] else [ LeaseCancel( LEASEID ) ]
let lease = if( leased_new == 0 ) then
{
[
DeleteEntry( kLEASEID ),
DeleteEntry( kLEASED )
]
}
else
{
let lease = Lease( NODE, leased_new, if( LEASEID == NOLEASEID ) then 0 else LEASEID.toInt() )
[
lease,
BinaryEntry( kLEASEID, calculateLeaseId( lease ) ),
IntegerEntry( kLEASED, leased_new )
]
}
leaseCancel ++
lease
}
@Callable(i)
func init( node: String ) =
{
if( i.caller != this ) then throw( "init(): i.caller != this" ) else
if( !this.isDataStorageUntouched() ) then throw( "init(): !this.isDataStorageUntouched()" ) else
[
StringEntry( kNODE, node.addressFromStringValue().toString() )
]
}
@Callable(i)
func put() =
{
let payments = i.payments
if( payments.size() != 1 ) then throw( "put(): payments.size() != 1" ) else
let payment = payments[0]
if( payment.assetId != WAVES ) then throw( "put(): payment.assetId != WAVES" ) else
let amount_in = payment.amount
if( amount_in <= 0 ) then throw( "put(): amount <= 0" ) else
strict change = fraction( amount_in, PRECISION, RATE( amount_in ) )
sync( 0 )
++
[
totalRatedUpdate( change ),
userRatedUpdate( i.caller.toString(), change )
]
}
@Callable(i)
func get( amount: Int ) =
{
if( amount <= 0 && amount != -1 ) then throw( "get(): amount <= 0 && amount != -1" ) else
let payments = i.payments
if( payments.size() != 0 ) then throw( "get(): payments.size() != 0" ) else
let rated = userRated( i.caller.toString() )
let rate = RATE( 0 )
let total_user = fraction( rated, rate, PRECISION )
if( total_user == 0 ) then throw( "get(): total == 0" ) else
let target_amount = if( amount == -1 ) then total_user else amount
if( target_amount > total_user ) then throw( "get(): " + target_amount.toString() + " > " + total_user.toString() ) else
let remains = total_user - target_amount
let remains_rated = fraction( remains, PRECISION, rate )
strict change = remains_rated - rated
sync( target_amount )
++
[
totalRatedUpdate( change ),
userRatedUpdate( i.caller.toString(), change ),
ScriptTransfer( i.caller, target_amount, WAVES )
]
}
@Callable(i)
func amount() =
{
if( i.payments.size() != 0 ) then throw( "amount(): payments.size() != 0" ) else
let rated = userRated( i.caller.toString() )
let rate = RATE( 0 )
let total_user = fraction( rated, rate, PRECISION )
( [], total_user )
}
{-# STDLIB_VERSION 6 #-}
{-# CONTENT_TYPE DAPP #-}
{-# SCRIPT_TYPE ACCOUNT #-}
let WAVES = unit
let kDAPP = "DAPP"
let DAPP = this.getStringValue( kDAPP ).addressFromStringValue()
let minimal = 10_0000_0000
@Callable(i)
func init( dApp: String ) =
{
if( i.caller != this ) then throw( "init(): i.caller != this" ) else
if( !this.isDataStorageUntouched() ) then throw( "init(): !this.isDataStorageUntouched()" ) else
[
StringEntry( kDAPP, dApp.addressFromStringValue().toString() )
]
}
@Callable(i)
func claim() =
{
let caller = i.caller
if( caller != DAPP ) then throw( "claim(): caller != DAPP" ) else
let available = wavesBalance( this ).available
if( available <= minimal ) then [] else
[
ScriptTransfer( caller, available - minimal, WAVES )
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment